[UNIATA] Fix 64 bit issues
[reactos.git] / drivers / storage / ide / uniata / id_init.cpp
1 /*++
2
3 Copyright (c) 2004-2016 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 case ATA_JMICRON_ID:
283 /* New JMicron PATA controllers */
284 if(deviceExtension->DevID == ATA_JMB361 ||
285 deviceExtension->DevID == ATA_JMB363 ||
286 deviceExtension->DevID == ATA_JMB368) {
287 if(BMList[deviceExtension->DevIndex].channel) {
288 KdPrint2((PRINT_PREFIX "New JMicron has no 2nd chan\n"));
289 return FALSE;
290 }
291 deviceExtension->NumberChannels = 1;
292 KdPrint2((PRINT_PREFIX "New JMicron PATA 1 chan\n"));
293 }
294 break;
295 case ATA_CYRIX_ID:
296 if(ChipType == CYRIX_OLD) {
297 UCHAR tmp8;
298 ULONG slotNumber;
299 slotNumber = deviceExtension->slotNumber;
300 KdPrint2((PRINT_PREFIX "Cyrix slot %#x\n", slotNumber));
301 GetPciConfig1(0x60, tmp8);
302 if(tmp8 & (1 << BMList[deviceExtension->DevIndex].channel)) {
303 KdPrint2((PRINT_PREFIX "Old Cyrix chan %d ok\n", BMList[deviceExtension->DevIndex].channel));
304 } else {
305 KdPrint2((PRINT_PREFIX "Old Cyrix no chan %d\n", BMList[deviceExtension->DevIndex].channel));
306 return FALSE;
307 }
308 }
309 break;
310 } // end switch(VendorID)
311
312 i = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NumberChannels", n);
313 if(!i) {
314 i = n;
315 }
316 KdPrint2((PRINT_PREFIX "reg -> %d chans\n", n));
317
318 deviceExtension->NumberChannels = min(i, deviceExtension->NumberChannels);
319 if(!deviceExtension->NumberChannels) {
320 KdPrint2((PRINT_PREFIX "all channels blocked\n", n));
321 return FALSE;
322 }
323 deviceExtension->AHCI_PI_mask &= (ULONG)0xffffffff >> (32-deviceExtension->NumberChannels);
324 KdPrint2((PRINT_PREFIX "Final PortMask %#x\n", deviceExtension->AHCI_PI_mask));
325
326 return TRUE;
327
328 } // end UniataChipDetectChannels()
329
330 NTSTATUS
331 NTAPI
332 UniataChipDetect(
333 IN PVOID HwDeviceExtension,
334 IN PPCI_COMMON_CONFIG pciData, // optional
335 IN ULONG DeviceNumber,
336 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
337 IN BOOLEAN* simplexOnly
338 )
339 {
340 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
341 ULONG slotNumber = deviceExtension->slotNumber;
342 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
343 ULONG VendorID = deviceExtension->DevID & 0xffff;
344 ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
345 ULONG RevID = deviceExtension->RevID;
346 ULONG i, c;
347 BUSMASTER_CONTROLLER_INFORMATION_BASE* DevTypeInfo;
348 PHW_CHANNEL chan;
349 ULONG ChipType;
350 ULONG ChipFlags;
351 ULONG tmp32;
352 UCHAR tmp8;
353 #ifdef __REACTOS__
354 ULONG_PTR BaseMemAddress;
355 ULONG_PTR BaseIoAddress1;
356 ULONG_PTR BaseIoAddress2;
357 ULONG_PTR BaseIoAddressBM;
358 #else
359 ULONG BaseMemAddress;
360 ULONG BaseIoAddress1;
361 ULONG BaseIoAddress2;
362 ULONG BaseIoAddressBM;
363 #endif
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 #ifdef __REACTOS__
1214 ScsiPortFreeDeviceBase(HwDeviceExtension, (PCHAR)(ULONG_PTR)BaseIoAddressBM);
1215 #else
1216 ScsiPortFreeDeviceBase(HwDeviceExtension, (PCHAR)BaseIoAddressBM);
1217 #endif
1218 UniataInitIoResEx(&deviceExtension->BaseIoAddressBM_0, 0, 0, FALSE);
1219
1220 if(tmp8 == 0xff) {
1221 KdPrint2((PRINT_PREFIX "invalid BM status, keep AHCI mode\n"));
1222 break;
1223 }
1224 }
1225 KdPrint2((PRINT_PREFIX "Compatible mode, reallocate LUNs\n"));
1226 deviceExtension->NumberLuns = 2; // we may be in Legacy mode
1227 if(!UniataAllocateLunExt(deviceExtension, 2)) {
1228 KdPrint2((PRINT_PREFIX "can't re-allocate Luns\n"));
1229 return STATUS_UNSUCCESSFUL;
1230 }
1231 }
1232 deviceExtension->HwFlags &= ~UNIATA_AHCI;
1233
1234 MemIo = FALSE;
1235 /* if BAR(5) is IO it should point to SATA interface registers */
1236 if(OrigAHCI) {
1237 /* Skip BAR(5) in compatible mode */
1238 KdPrint2((PRINT_PREFIX "Ignore BAR5 on compatible\n"));
1239 BaseMemAddress = 0;
1240 } else
1241 if(deviceExtension->DevID == 0x28288086 &&
1242 pciData->u.type0.SubVendorID == 0x106b) {
1243 /* Skip BAR(5) on ICH8M Apples, system locks up on access. */
1244 KdPrint2((PRINT_PREFIX "Ignore BAR5 on ICH8M Apples\n"));
1245 BaseMemAddress = 0;
1246 } else {
1247 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
1248 5, 0, 0x10);
1249 if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
1250 KdPrint2((PRINT_PREFIX "MemIo[5]\n"));
1251 MemIo = TRUE;
1252 }
1253 }
1254 UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE);
1255
1256 for(c=0; c<deviceExtension->NumberChannels; c++) {
1257 chan = &deviceExtension->chan[c];
1258 IsPata = FALSE;
1259 if(ChipFlags & ICH5) {
1260 KdPrint2((PRINT_PREFIX "ICH5\n"));
1261 if ((tmp8 & 0x04) == 0) {
1262 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1263 } else if ((tmp8 & 0x02) == 0) {
1264 if(c != 0) {
1265 IsPata = TRUE;
1266 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1267 }
1268 } else if ((tmp8 & 0x02) != 0) {
1269 if(c != 1) {
1270 IsPata = TRUE;
1271 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1272 }
1273 }
1274 } else
1275 if(ChipFlags & I6CH2) {
1276 KdPrint2((PRINT_PREFIX "I6CH2\n"));
1277 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1278 } else {
1279 KdPrint2((PRINT_PREFIX "other Intel\n"));
1280 switch(tmp8 & 0x03) {
1281 case 2:
1282 if(c!=0) {
1283 // PATA
1284 IsPata = TRUE;
1285 }
1286 break;
1287 case 1:
1288 if(c!=1) {
1289 // PATA
1290 IsPata = TRUE;
1291 }
1292 break;
1293 }
1294 }
1295
1296 if(IsPata) {
1297 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
1298 KdPrint2((PRINT_PREFIX "PATA part\n"));
1299 } else {
1300
1301 if(!(ChipFlags & ICH7) && BaseMemAddress) {
1302 KdPrint2((PRINT_PREFIX "BaseMemAddress[5] -> indexed\n"));
1303 UniataInitIoRes(chan, IDX_INDEXED_ADDR, BaseMemAddress + 0, MemIo, FALSE);
1304 UniataInitIoRes(chan, IDX_INDEXED_DATA, BaseMemAddress + 4, MemIo, FALSE);
1305 }
1306 if((ChipFlags & ICH5) || BaseMemAddress) {
1307
1308 KdPrint2((PRINT_PREFIX "io proc()\n"));
1309 // Rather interesting way of register access...
1310 ChipType = INTEL_IDX;
1311 deviceExtension->HwFlags &= ~CHIPTYPE_MASK;
1312 deviceExtension->HwFlags |= ChipType;
1313
1314 if(ChipFlags & ICH7) {
1315 KdPrint2((PRINT_PREFIX "ICH7 way\n"));
1316 }
1317 UniataInitIoRes(chan, IDX_SATA_SStatus, 0x200*c + 0, FALSE, TRUE); // this is fake non-zero value
1318 UniataInitIoRes(chan, IDX_SATA_SError, 0x200*c + 2, FALSE, TRUE);
1319 UniataInitIoRes(chan, IDX_SATA_SControl, 0x200*c + 1, FALSE, TRUE);
1320 }
1321 }
1322
1323 } // end for()
1324
1325 // rest of INIT staff is in AtapiChipInit()
1326
1327 } // ATA_SA150
1328 break; }
1329 case ATA_CYRIX_ID:
1330 /* Cyrix 5530 ATA33 controller */
1331 if(deviceExtension->DevID == 0x01021078) {
1332 ConfigInfo->AlignmentMask = 0x0f;
1333 deviceExtension->MaximumDmaTransferLength = 63*1024;
1334 }
1335 break;
1336 case ATA_JMICRON_ID:
1337 /* New JMicron PATA controllers */
1338 GetPciConfig1(0xdf, tmp8);
1339 if(tmp8 & 0x40) {
1340 KdPrint((" Check JMicron AHCI\n"));
1341 if(Ata_is_ahci_dev(pciData)) {
1342 ChipFlags |= UNIATA_AHCI;
1343 deviceExtension->HwFlags |= UNIATA_AHCI;
1344 } else {
1345 KdPrint((" JMicron PATA\n"));
1346 }
1347 } else {
1348 /* set controller configuration to a combined setup we support */
1349 SetPciConfig4(0x40, 0x80c0a131);
1350 SetPciConfig4(0x80, 0x01200000);
1351 //KdPrint((" JMicron Combined (not supported yet)\n"));
1352 //return STATUS_NOT_FOUND;
1353 }
1354 break;
1355 }
1356
1357 return STATUS_SUCCESS;
1358
1359 } // end UniataChipDetect()
1360
1361
1362 /*
1363 Do some 'magic staff' for VIA SouthBridge
1364 This will prevent data losses
1365 */
1366 VOID
1367 NTAPI
1368 AtapiViaSouthBridgeFixup(
1369 IN PVOID HwDeviceExtension,
1370 IN BUS_DATA_TYPE BusDataType,
1371 IN ULONG SystemIoBusNumber,
1372 IN ULONG slotNumber
1373 )
1374 {
1375 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1376 PCI_COMMON_CONFIG pciData;
1377 ULONG funcNumber;
1378 ULONG busDataRead;
1379
1380 ULONG VendorID;
1381 ULONG DeviceID;
1382 PCI_SLOT_NUMBER slotData;
1383 ULONG dev_id;
1384 BOOLEAN found = FALSE;
1385
1386 slotData.u.AsULONG = slotNumber;
1387 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
1388
1389 slotData.u.bits.FunctionNumber = funcNumber;
1390
1391 busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1392 PCIConfiguration,
1393 SystemIoBusNumber,
1394 slotData.u.AsULONG,
1395 &pciData,
1396 PCI_COMMON_HDR_LENGTH);
1397
1398 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1399 continue;
1400 }
1401
1402 VendorID = pciData.VendorID;
1403 DeviceID = pciData.DeviceID;
1404 dev_id = (VendorID | (DeviceID << 16));
1405
1406 if (dev_id == 0x03051106 || /* VIA VT8363 */
1407 dev_id == 0x03911106 || /* VIA VT8371 */
1408 dev_id == 0x31021106 || /* VIA VT8662 */
1409 dev_id == 0x31121106) { /* VIA VT8361 */
1410 UCHAR reg76;
1411
1412 GetPciConfig1(0x76, reg76);
1413
1414 if ((reg76 & 0xf0) != 0xd0) {
1415 SetPciConfig1(0x75, 0x80);
1416 SetPciConfig1(0x76, (reg76 & 0x0f) | 0xd0);
1417 }
1418 found = TRUE;
1419 break;
1420 }
1421 }
1422 if(!found) {
1423 deviceExtension->HwFlags &= ~VIABUG;
1424 }
1425 } // end AtapiViaSouthBridgeFixup()
1426
1427 /*
1428 Do some 'magic staff' for ROSB SouthBridge
1429 This will prevent data losses
1430 */
1431 VOID
1432 NTAPI
1433 AtapiRosbSouthBridgeFixup(
1434 IN PVOID HwDeviceExtension,
1435 IN BUS_DATA_TYPE BusDataType,
1436 IN ULONG SystemIoBusNumber,
1437 IN ULONG slotNumber
1438 )
1439 {
1440 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1441 PCI_COMMON_CONFIG pciData;
1442 ULONG funcNumber;
1443 ULONG busDataRead;
1444
1445 ULONG VendorID;
1446 ULONG DeviceID;
1447 PCI_SLOT_NUMBER slotData;
1448 ULONG dev_id;
1449 // BOOLEAN found = FALSE;
1450
1451 /* locate the ISA part in the southbridge and enable UDMA33 */
1452 slotData.u.AsULONG = slotNumber;
1453 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
1454
1455 slotData.u.bits.FunctionNumber = funcNumber;
1456
1457 busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1458 PCIConfiguration,
1459 SystemIoBusNumber,
1460 slotData.u.AsULONG,
1461 &pciData,
1462 PCI_COMMON_HDR_LENGTH);
1463
1464 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1465 continue;
1466 }
1467
1468 VendorID = pciData.VendorID;
1469 DeviceID = pciData.DeviceID;
1470 dev_id = (VendorID | (DeviceID << 16));
1471
1472 if (dev_id == ATA_ROSB4_ISA) { /* */
1473 ChangePciConfig4(0x64, ((a & ~0x00002000) | 0x00004000));
1474 break;
1475 }
1476 }
1477 } // end AtapiRosbSouthBridgeFixup()
1478
1479 /*
1480 Do some 'magic staff' for ROSB SouthBridge
1481 This will prevent data losses
1482 */
1483 VOID
1484 NTAPI
1485 AtapiAliSouthBridgeFixup(
1486 IN PVOID HwDeviceExtension,
1487 IN BUS_DATA_TYPE BusDataType,
1488 IN ULONG SystemIoBusNumber,
1489 IN ULONG slotNumber,
1490 IN ULONG c
1491 )
1492 {
1493 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1494 PCI_COMMON_CONFIG pciData;
1495 ULONG funcNumber;
1496 ULONG busDataRead;
1497
1498 ULONG VendorID;
1499 ULONG DeviceID;
1500 PCI_SLOT_NUMBER slotData;
1501 ULONG dev_id;
1502 // BOOLEAN found = FALSE;
1503
1504 /* workaround for datacorruption bug found on at least SUN Blade-100
1505 * find the ISA function on the southbridge and disable then enable
1506 * the ATA channel tristate buffer */
1507 slotData.u.AsULONG = slotNumber;
1508 for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
1509
1510 slotData.u.bits.FunctionNumber = funcNumber;
1511
1512 busDataRead = ScsiPortGetBusData(HwDeviceExtension,
1513 PCIConfiguration,
1514 SystemIoBusNumber,
1515 slotData.u.AsULONG,
1516 &pciData,
1517 PCI_COMMON_HDR_LENGTH);
1518
1519 if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
1520 continue;
1521 }
1522
1523 VendorID = pciData.VendorID;
1524 DeviceID = pciData.DeviceID;
1525 dev_id = (VendorID | (DeviceID << 16));
1526
1527 if (dev_id == ATA_ALI_1533) { /* SOUTH */
1528 ChangePciConfig1(0x58, (a & ~(0x04 << c)));
1529 ChangePciConfig1(0x58, (a | (0x04 << c)));
1530 break;
1531 }
1532 }
1533 } // end AtapiRosbSouthBridgeFixup()
1534
1535 ULONG
1536 NTAPI
1537 hpt_cable80(
1538 IN PHW_DEVICE_EXTENSION deviceExtension,
1539 IN ULONG channel // physical channel number (0-1)
1540 )
1541 {
1542 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1543 ULONG slotNumber = deviceExtension->slotNumber;
1544 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1545
1546 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1547
1548 UCHAR reg, val, res;
1549 PCI_SLOT_NUMBER slotData;
1550
1551 PHW_CHANNEL chan;
1552 ULONG c; // logical channel (for Compatible Mode controllers)
1553
1554 c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1555 chan = &deviceExtension->chan[c];
1556
1557 slotData.u.AsULONG = deviceExtension->slotNumber;
1558
1559 if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
1560 KdPrint2((PRINT_PREFIX "UNIATA_NO80CHK\n"));
1561 return TRUE;
1562 }
1563
1564 if(ChipType == HPT374 && slotData.u.bits.FunctionNumber == 1) {
1565 reg = channel ? 0x57 : 0x53;
1566 GetPciConfig1(reg, val);
1567 SetPciConfig1(reg, val | 0x80);
1568 }
1569 else {
1570 reg = 0x5b;
1571 GetPciConfig1(reg, val);
1572 SetPciConfig1(reg, val & 0xfe);
1573 }
1574 GetPciConfig1(0x5a, res);
1575 res = res & (channel ? 0x01 : 0x02);
1576 SetPciConfig1(reg, val);
1577 if(chan->Force80pin) {
1578 KdPrint2((PRINT_PREFIX "Force80pin\n"));
1579 res = 0;
1580 }
1581 KdPrint2((PRINT_PREFIX "hpt_cable80(%d) = %d\n", channel, !res));
1582 return !res;
1583 } // end hpt_cable80()
1584
1585 /*
1586 ULONG
1587 NTAPI
1588 via_cable80(
1589 IN PHW_DEVICE_EXTENSION deviceExtension,
1590 IN ULONG channel // physical channel number (0-1)
1591 )
1592 {
1593 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1594 ULONG slotNumber = deviceExtension->slotNumber;
1595 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1596
1597 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1598
1599 ULONG reg50;
1600 ULONG a;
1601 ULONG i, j;
1602 BOOLEAN res;
1603
1604 GetPciConfig1(0x50, reg50);
1605
1606 switch(ChipType) {
1607 case VIA133:
1608 a = 8;
1609 break;
1610 case VIA100:
1611 a = 4;
1612 break;
1613 case VIA66:
1614 a = 2;
1615 break;
1616 default:
1617 return false;
1618 }
1619
1620 res = FALSE;
1621 for (j=0; j>=2; i -= 8) {
1622 i = (3-(channel*2+j))*8;
1623 if (((reg50 >> (i & 0x10)) & 8) &&
1624 ((reg50 >> i) & 0x20) &&
1625 (((reg50 >> i) & 7) < a)) {
1626
1627 res |= TRUE; //(1 << (1 - (i >> 4)));
1628 }
1629 }
1630 KdPrint2((PRINT_PREFIX "via_cable80(%d) = %d\n", channel, res));
1631 return res;
1632
1633 } // end via_cable80()
1634 */
1635
1636 BOOLEAN
1637 NTAPI
1638 generic_cable80(
1639 IN PHW_DEVICE_EXTENSION deviceExtension,
1640 IN ULONG channel, // physical channel number (0-1)
1641 IN ULONG pci_reg,
1642 IN ULONG bit_offs
1643 )
1644 {
1645 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1646 ULONG slotNumber = deviceExtension->slotNumber;
1647 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1648
1649 if(deviceExtension->MaxTransferMode <= ATA_UDMA2) {
1650 KdPrint2((PRINT_PREFIX "generic_cable80(%d, %#x, %d) <= UDMA2\n", channel, pci_reg, bit_offs));
1651 return FALSE;
1652 }
1653
1654 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1655 PHW_CHANNEL chan;
1656 ULONG c; // logical channel (for Compatible Mode controllers)
1657 UCHAR tmp8;
1658
1659 c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1660 chan = &deviceExtension->chan[c];
1661
1662 if(chan->Force80pin) {
1663 KdPrint2((PRINT_PREFIX "Force80pin\n"));
1664 return TRUE;
1665 }
1666
1667 GetPciConfig1(pci_reg, tmp8);
1668 if(!(tmp8 & (1 << (channel << bit_offs)))) {
1669 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1670 KdPrint2((PRINT_PREFIX "generic_cable80(%d, %#x, %d) = 0\n", channel, pci_reg, bit_offs));
1671 return FALSE;
1672 }
1673
1674 KdPrint2((PRINT_PREFIX "generic_cable80(%d, %#x, %d) = 1\n", channel, pci_reg, bit_offs));
1675 return TRUE;
1676 } // end generic_cable80()
1677
1678 VOID
1679 NTAPI
1680 UniAtaReadLunConfig(
1681 IN PHW_DEVICE_EXTENSION deviceExtension,
1682 IN ULONG channel, // physical channel
1683 IN ULONG DeviceNumber
1684 )
1685 {
1686 ULONG tmp32;
1687 PHW_CHANNEL chan;
1688 PHW_LU_EXTENSION LunExt;
1689 ULONG c;
1690
1691 c = channel - deviceExtension->Channel; // logical channel
1692
1693 chan = &deviceExtension->chan[c];
1694 DeviceNumber = (DeviceNumber % deviceExtension->NumberLuns);
1695 LunExt = chan->lun[DeviceNumber];
1696
1697 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadCacheEnable", 1);
1698 LunExt->opt_ReadCacheEnable = tmp32 ? TRUE : FALSE;
1699
1700 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"WriteCacheEnable", 1);
1701 LunExt->opt_WriteCacheEnable = tmp32 ? TRUE : FALSE;
1702
1703 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"MaxTransferMode", chan->MaxTransferMode);
1704 LunExt->opt_MaxTransferMode = tmp32;
1705
1706 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"PreferedTransferMode", 0xffffffff);
1707 LunExt->opt_PreferedTransferMode = tmp32;
1708
1709 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"AdvancedPowerMode", ATA_C_F_APM_CNT_MIN_NO_STANDBY);
1710 if(tmp32 > 0xfe) {
1711 tmp32 = 0xfe; // max. performance
1712 }
1713 LunExt->opt_AdvPowerMode = (UCHAR)tmp32;
1714
1715 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"AcousticMgmt", ATA_C_F_AAM_CNT_MAX_POWER_SAVE);
1716 if(tmp32 > 0xfe) {
1717 tmp32 = 0xfe; // max. performance
1718 } else
1719 if(tmp32 < 0x80) {
1720 tmp32 = 0x0; // disable feature
1721 }
1722 LunExt->opt_AcousticMode = (UCHAR)tmp32;
1723
1724 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"StandbyTimer", 0);
1725 if(tmp32 == 0xfe) {
1726 tmp32 = 0xff;
1727 }
1728 LunExt->opt_StandbyTimer = (UCHAR)tmp32;
1729
1730 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadOnly", 0);
1731 if(tmp32 <= 2) {
1732 LunExt->opt_ReadOnly = (UCHAR)tmp32;
1733 }
1734
1735 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"GeomType", 0xffffffff);
1736 if(tmp32 > GEOM_MANUAL) {
1737 tmp32 = 0xffffffff;
1738 }
1739 LunExt->opt_GeomType = tmp32;
1740 if(tmp32 == GEOM_MANUAL) {
1741 LunExt->DeviceFlags |= DFLAGS_MANUAL_CHS;
1742 LunExt->opt_GeomType = GEOM_ORIG;
1743 // assume IdentifyData is already zero-filled
1744 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"C", 0);
1745 LunExt->IdentifyData.NumberOfCurrentCylinders =
1746 LunExt->IdentifyData.NumberOfCylinders = (USHORT)tmp32;
1747 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"H", 0);
1748 LunExt->IdentifyData.NumberOfCurrentHeads =
1749 LunExt->IdentifyData.NumberOfHeads = (USHORT)tmp32;
1750 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"S", 0);
1751 LunExt->IdentifyData.CurrentSectorsPerTrack =
1752 LunExt->IdentifyData.SectorsPerTrack = (USHORT)tmp32;
1753 memcpy(LunExt->IdentifyData.ModelNumber, "SEIDH DD", 8); // ESDI HDD
1754 memcpy(LunExt->IdentifyData.SerialNumber, ".10", 4);
1755 memcpy(LunExt->IdentifyData.FirmwareRevision, ".10", 4);
1756 if(!LunExt->IdentifyData.SectorsPerTrack ||
1757 !LunExt->IdentifyData.NumberOfCylinders ||
1758 !LunExt->IdentifyData.NumberOfHeads) {
1759 // ERROR
1760 KdPrint2((PRINT_PREFIX "Wrong CHS\n"));
1761 LunExt->opt_GeomType = GEOM_AUTO;
1762 } else {
1763 LunExt->DeviceFlags |= DFLAGS_MANUAL_CHS;
1764 LunExt->opt_GeomType = GEOM_ORIG;
1765 }
1766 }
1767
1768 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"Hidden", 0);
1769 if(tmp32) {
1770 LunExt->DeviceFlags |= DFLAGS_HIDDEN;
1771 }
1772 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"Exclude", 0);
1773 if(tmp32) {
1774 LunExt->DeviceFlags |= DFLAGS_HIDDEN;
1775 }
1776
1777 return;
1778 } // end UniAtaReadLunConfig()
1779
1780 BOOLEAN
1781 NTAPI
1782 AtapiReadChipConfig(
1783 IN PVOID HwDeviceExtension,
1784 IN ULONG DeviceNumber,
1785 IN ULONG channel // physical channel
1786 )
1787 {
1788 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1789 PHW_CHANNEL chan;
1790 ULONG tmp32;
1791 ULONG c; // logical channel (for Compatible Mode controllers)
1792 ULONG i;
1793
1794 KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: devExt %#x\n", deviceExtension ));
1795 ASSERT(deviceExtension);
1796
1797 if(channel != CHAN_NOT_SPECIFIED) {
1798 c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1799 } else {
1800 c = CHAN_NOT_SPECIFIED;
1801 }
1802
1803 KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber, channel ));
1804
1805 if(channel == CHAN_NOT_SPECIFIED) {
1806 if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", FALSE)) {
1807 deviceExtension->simplexOnly = TRUE;
1808 }
1809 deviceExtension->opt_AtapiDmaZeroTransfer = FALSE;
1810 deviceExtension->opt_AtapiDmaControlCmd = FALSE;
1811 deviceExtension->opt_AtapiDmaRawRead = g_opt_AtapiDmaRawRead;
1812 deviceExtension->opt_AtapiDmaReadWrite = TRUE;
1813 }
1814
1815 if(c == CHAN_NOT_SPECIFIED) {
1816 KdPrint2((PRINT_PREFIX "MaxTransferMode (base): %#x\n", deviceExtension->MaxTransferMode));
1817 for(c=0; c<deviceExtension->NumberChannels; c++) {
1818 chan = &deviceExtension->chan[c];
1819 chan->MaxTransferMode = deviceExtension->MaxTransferMode;
1820 tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", chan->MaxTransferMode);
1821 if(tmp32 != 0xffffffff) {
1822 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
1823 chan->MaxTransferMode = tmp32;
1824 }
1825 tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"Force80pin", FALSE);
1826 chan->Force80pin = tmp32 ? TRUE : FALSE;
1827 if(chan->Force80pin) {
1828 KdPrint2((PRINT_PREFIX "Force80pin on chip\n"));
1829 deviceExtension->HwFlags |= UNIATA_NO80CHK;
1830 }
1831
1832 //UniAtaReadLunConfig(deviceExtension, c, 0);
1833 //UniAtaReadLunConfig(deviceExtension, c, 1);
1834 }
1835
1836 deviceExtension->opt_AtapiDmaZeroTransfer =
1837 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaZeroTransfer", deviceExtension->opt_AtapiDmaZeroTransfer) ?
1838 TRUE : FALSE;
1839
1840 deviceExtension->opt_AtapiDmaControlCmd =
1841 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaControlCmd", deviceExtension->opt_AtapiDmaControlCmd) ?
1842 TRUE : FALSE;
1843
1844 deviceExtension->opt_AtapiDmaRawRead =
1845 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead", deviceExtension->opt_AtapiDmaRawRead) ?
1846 TRUE : FALSE;
1847
1848 deviceExtension->opt_AtapiDmaReadWrite =
1849 AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaReadWrite", deviceExtension->opt_AtapiDmaReadWrite) ?
1850 TRUE : FALSE;
1851
1852 } else {
1853 chan = &deviceExtension->chan[c];
1854 chan->MaxTransferMode = deviceExtension->MaxTransferMode;
1855 tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", chan->MaxTransferMode);
1856 if(tmp32 != 0xffffffff) {
1857 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
1858 chan->MaxTransferMode = tmp32;
1859 }
1860 tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"ReorderEnable", TRUE);
1861 chan->UseReorder = tmp32 ? TRUE : FALSE;
1862
1863 tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"Force80pin", FALSE);
1864 chan->Force80pin = tmp32 ? TRUE : FALSE;
1865 if(chan->Force80pin) {
1866 KdPrint2((PRINT_PREFIX "Force80pin on channel\n"));
1867 }
1868
1869 for(i=0; i<deviceExtension->NumberLuns; i++) {
1870 UniAtaReadLunConfig(deviceExtension, channel, i);
1871 }
1872 }
1873
1874 return TRUE;
1875 } // end AtapiReadChipConfig()
1876
1877 BOOLEAN
1878 NTAPI
1879 AtapiChipInit(
1880 IN PVOID HwDeviceExtension,
1881 IN ULONG DeviceNumber,
1882 IN ULONG channel // logical channel
1883 )
1884 {
1885 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1886 ULONG slotNumber = deviceExtension->slotNumber;
1887 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1888 ULONG VendorID = deviceExtension->DevID & 0xffff;
1889 ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
1890 ULONG RevID = deviceExtension->RevID;
1891 // ULONG i;
1892 // BUSMASTER_CONTROLLER_INFORMATION_BASE* DevTypeInfo;
1893 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1894 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
1895 PHW_CHANNEL chan;
1896 UCHAR tmp8;
1897 USHORT tmp16;
1898 ULONG tmp32;
1899 ULONG c; // logical channel (for Compatible Mode controllers)
1900 BOOLEAN CheckCable = FALSE;
1901 BOOLEAN GlobalInit = FALSE;
1902 //ULONG BaseIoAddress;
1903
1904 switch(channel) {
1905 case CHAN_NOT_SPECIFIED_CHECK_CABLE:
1906 CheckCable = TRUE;
1907 /* FALLTHROUGH */
1908 case CHAN_NOT_SPECIFIED:
1909 c = CHAN_NOT_SPECIFIED;
1910 GlobalInit = TRUE;
1911 break;
1912 default:
1913 //c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1914 c = channel;
1915 channel += deviceExtension->Channel;
1916 }
1917
1918 KdPrint2((PRINT_PREFIX "AtapiChipInit: dev %#x, ph chan %d, c %d\n", DeviceNumber, channel, c));
1919
1920 KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
1921 KdPrint2((PRINT_PREFIX "VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID, DeviceID, RevID));
1922
1923 if(deviceExtension->UnknownDev) {
1924 KdPrint2((PRINT_PREFIX " Unknown chip\n" ));
1925 //return TRUE;
1926 VendorID = 0xffffffff;
1927 }
1928
1929
1930 if(ChipFlags & UNIATA_AHCI) {
1931 /* if BAR(5) is IO it should point to SATA interface registers */
1932 if(!deviceExtension->BaseIoAHCI_0.Addr) {
1933 KdPrint2((PRINT_PREFIX " !BaseIoAHCI_0, exiting\n" ));
1934 return FALSE;
1935 }
1936 if(c == CHAN_NOT_SPECIFIED) {
1937 return UniataAhciInit(HwDeviceExtension);
1938 } else
1939 if(c<deviceExtension->NumberChannels) {
1940 KdPrint2((PRINT_PREFIX " AHCI single channel init\n" ));
1941 UniataAhciReset(HwDeviceExtension, c);
1942 return TRUE;
1943 } else {
1944 KdPrint2((PRINT_PREFIX " AHCI non-existent channel\n" ));
1945 return FALSE;
1946 }
1947 }
1948
1949 if((WinVer_Id() > WinVer_NT) &&
1950 GlobalInit &&
1951 deviceExtension->MasterDev) {
1952 PCI_COMMON_CONFIG pciData;
1953 ULONG busDataRead;
1954
1955 KdPrint2((PRINT_PREFIX " re-enable IO resources of MasterDev\n" ));
1956
1957 busDataRead = HalGetBusData
1958 //ScsiPortGetBusData
1959 (
1960 //HwDeviceExtension,
1961 PCIConfiguration, SystemIoBusNumber, slotNumber,
1962 &pciData, PCI_COMMON_HDR_LENGTH);
1963 if(busDataRead == PCI_COMMON_HDR_LENGTH) {
1964 UniataEnableIoPCI(SystemIoBusNumber, slotNumber, &pciData);
1965 } else {
1966 KdPrint2((PRINT_PREFIX " re-enable IO resources of MasterDev FAILED\n" ));
1967 }
1968 }
1969
1970 switch(VendorID) {
1971 // case ATA_ACARD_ID:
1972 // break;
1973 case ATA_ACER_LABS_ID:
1974 if(ChipFlags & UNIATA_SATA) {
1975 if(c == CHAN_NOT_SPECIFIED) {
1976 for(c=0; c<deviceExtension->NumberChannels; c++) {
1977 chan = &deviceExtension->chan[c];
1978 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
1979 /* the southbridge might need the data corruption fix */
1980 if(RevID == 0xc2 || RevID == 0xc3) {
1981 AtapiAliSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
1982 SystemIoBusNumber, slotNumber, c);
1983 }
1984 }
1985 /* enable PCI interrupt */
1986 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
1987 }
1988 } else
1989 if(ChipFlags & ALINEW) {
1990 if(c == CHAN_NOT_SPECIFIED) {
1991 /* use device interrupt as byte count end */
1992 ChangePciConfig1(0x4a, (a | 0x20));
1993 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
1994 if(RevID < 0xc7) {
1995 ChangePciConfig1(0x4b, (a | 0x09));
1996 }
1997
1998 /* enable ATAPI UDMA mode */
1999 ChangePciConfig1(0x53, (a | (RevID >= 0xc7 ? 0x03 : 0x01)));
2000
2001 } else {
2002 // check 80-pin cable
2003 generic_cable80(deviceExtension, channel, 0x4a, 0);
2004 }
2005 } else {
2006 if(c == CHAN_NOT_SPECIFIED) {
2007 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
2008 ChangePciConfig1(0x53, (a | 0x03));
2009 } else {
2010 // ATAPI DMA R/O
2011 deviceExtension->chan[c].ChannelCtrlFlags |= CTRFLAGS_DMA_RO;
2012 }
2013 }
2014 break;
2015 case ATA_AMD_ID:
2016 if(c == CHAN_NOT_SPECIFIED) {
2017 /* set prefetch, postwrite */
2018 if(ChipFlags & AMDBUG) {
2019 ChangePciConfig1(0x41, (a & 0x0f));
2020 } else {
2021 ChangePciConfig1(0x41, (a | 0xf0));
2022 }
2023 }
2024 if(deviceExtension->MaxTransferMode < ATA_UDMA2)
2025 break;
2026 // check 80-pin cable
2027 if(!(ChipFlags & UNIATA_NO80CHK)) {
2028 if(c == CHAN_NOT_SPECIFIED) {
2029 // do nothing
2030 } else {
2031 generic_cable80(deviceExtension, channel, 0x42, 0);
2032 }
2033 }
2034 break;
2035 case ATA_HIGHPOINT_ID:
2036
2037 if(c == CHAN_NOT_SPECIFIED) {
2038
2039 if(ChipFlags & HPTOLD) {
2040 /* turn off interrupt prediction */
2041 ChangePciConfig1(0x51, (a & ~0x80));
2042 } else {
2043 /* turn off interrupt prediction */
2044 ChangePciConfig1(0x51, (a & ~0x03));
2045 ChangePciConfig1(0x55, (a & ~0x03));
2046 /* turn on interrupts */
2047 ChangePciConfig1(0x5a, (a & ~0x10));
2048 /* set clocks etc */
2049 if(ChipType < HPT372) {
2050 SetPciConfig1(0x5b, 0x22);
2051 } else {
2052 ChangePciConfig1(0x5b, ((a & 0x01) | 0x20));
2053 }
2054 }
2055
2056 } else {
2057 // check 80-pin cable
2058 chan = &deviceExtension->chan[c];
2059 if(!hpt_cable80(deviceExtension, channel)) {
2060 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2061 }
2062 }
2063 break;
2064 case ATA_INTEL_ID: {
2065 BOOLEAN IsPata;
2066 USHORT reg54;
2067 if(ChipFlags & UNIATA_SATA) {
2068
2069 KdPrint2((PRINT_PREFIX "Intel SATA\n"));
2070 if(ChipFlags & UNIATA_AHCI) {
2071 KdPrint2((PRINT_PREFIX "Do nothing for AHCI\n"));
2072 /* enable PCI interrupt */
2073 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
2074 break;
2075 }
2076 if(c == CHAN_NOT_SPECIFIED) {
2077 KdPrint2((PRINT_PREFIX "Base init\n"));
2078 /* force all ports active "the legacy way" */
2079 ChangePciConfig2(0x92, (a | 0x0f));
2080
2081 if(deviceExtension->BaseIoAddressSATA_0.Addr && (ChipFlags & ICH7)) {
2082 /* Set SCRAE bit to enable registers access. */
2083 ChangePciConfig4(0x94, (a | (1 << 9)));
2084 /* Set Ports Implemented register bits. */
2085 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x0c,
2086 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x0c) | 0x0f);
2087 }
2088 /* enable PCI interrupt */
2089 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
2090
2091 } else {
2092
2093 KdPrint2((PRINT_PREFIX "channel init\n"));
2094
2095 GetPciConfig1(0x90, tmp8);
2096 KdPrint2((PRINT_PREFIX "reg 90: %x, init lun map\n", tmp8));
2097
2098 KdPrint2((PRINT_PREFIX "chan %d\n", c));
2099 chan = &deviceExtension->chan[c];
2100 IsPata = FALSE;
2101 if(ChipFlags & ICH5) {
2102 KdPrint2((PRINT_PREFIX "ICH5\n"));
2103 if ((tmp8 & 0x04) == 0) {
2104 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
2105 chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ^ c;
2106 chan->lun[1]->SATA_lun_map = 0;
2107 } else if ((tmp8 & 0x02) == 0) {
2108 if(c == 0) {
2109 chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
2110 chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
2111 } else {
2112 IsPata = TRUE;
2113 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2114 }
2115 } else if ((tmp8 & 0x02) != 0) {
2116 if(c == 1) {
2117 chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
2118 chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
2119 } else {
2120 IsPata = TRUE;
2121 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2122 }
2123 }
2124 } else
2125 if(ChipFlags & I6CH2) {
2126 KdPrint2((PRINT_PREFIX "I6CH2\n"));
2127 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
2128 chan->lun[0]->SATA_lun_map = c ? 0 : 1;
2129 chan->lun[1]->SATA_lun_map = 0;
2130 } else {
2131 KdPrint2((PRINT_PREFIX "other Intel\n"));
2132 switch(tmp8 & 0x03) {
2133 case 0:
2134 KdPrint2((PRINT_PREFIX "0 -> %d/%d\n", 0+c, 2+c));
2135 chan->lun[0]->SATA_lun_map = 0+c;
2136 chan->lun[1]->SATA_lun_map = 2+c;
2137 break;
2138 case 2:
2139 if(c==0) {
2140 KdPrint2((PRINT_PREFIX "2 -> %d/%d\n", 0, 2));
2141 chan->lun[0]->SATA_lun_map = 0;
2142 chan->lun[1]->SATA_lun_map = 2;
2143 } else {
2144 // PATA
2145 KdPrint2((PRINT_PREFIX "PATA\n"));
2146 IsPata = TRUE;
2147 }
2148 break;
2149 case 1:
2150 if(c==1) {
2151 KdPrint2((PRINT_PREFIX "2 -> %d/%d\n", 1, 3));
2152 chan->lun[0]->SATA_lun_map = 1;
2153 chan->lun[1]->SATA_lun_map = 3;
2154 } else {
2155 // PATA
2156 KdPrint2((PRINT_PREFIX "PATA\n"));
2157 IsPata = TRUE;
2158 }
2159 break;
2160 }
2161 }
2162
2163 if(IsPata) {
2164 KdPrint2((PRINT_PREFIX "PATA part\n"));
2165 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
2166 }
2167
2168 if(ChipType == INTEL_IDX) {
2169 KdPrint2((PRINT_PREFIX "io indexed\n"));
2170 //for(c=0; c<deviceExtension->NumberChannels; c++) {
2171 chan = &deviceExtension->chan[c];
2172 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
2173 if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
2174 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 1);
2175 }
2176 //}
2177 }
2178 }
2179
2180 break;
2181 }
2182 if(deviceExtension->MaxTransferMode <= ATA_UDMA2)
2183 break;
2184 // check 80-pin cable
2185 if(c == CHAN_NOT_SPECIFIED) {
2186 // do nothing
2187 } else {
2188 chan = &deviceExtension->chan[c];
2189 GetPciConfig2(0x54, reg54);
2190 KdPrint2((PRINT_PREFIX " intel 80-pin check (reg54=%x)\n", reg54));
2191 if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
2192 KdPrint2((PRINT_PREFIX " No check (administrative)\n"));
2193 if(chan->Force80pin) {
2194 KdPrint2((PRINT_PREFIX "Force80pin\n"));
2195 }
2196 } else
2197 if(reg54 == 0x0000 || reg54 == 0xffff) {
2198 KdPrint2((PRINT_PREFIX " check failed (not supported)\n"));
2199 } else
2200 if( ((reg54 >> (channel*2)) & 30) == 0) {
2201 KdPrint2((PRINT_PREFIX " intel 40-pin\n"));
2202 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2203 }
2204 }
2205 break; }
2206 case ATA_NVIDIA_ID: {
2207 if(ChipFlags & UNIATA_SATA) {
2208 if(c == CHAN_NOT_SPECIFIED) {
2209 ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
2210 /* enable control access */
2211 ChangePciConfig1(0x50, (a | 0x04));
2212 /* MCP55 seems to need some time to allow r_res2 read. */
2213 AtapiStallExecution(10);
2214 KdPrint2((PRINT_PREFIX "BaseIoAddressSATA_0=%x\n", deviceExtension->BaseIoAddressSATA_0.Addr));
2215 if(ChipFlags & NVQ) {
2216 KdPrint2((PRINT_PREFIX "Disable NCQ\n"));
2217 tmp32 = AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400);
2218 KdPrint2((PRINT_PREFIX "MODE=%#x\n", tmp32));
2219 if(tmp32 & ~0xfffffff9) {
2220 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400,
2221 tmp32 & 0xfffffff9);
2222 }
2223 ChipFlags &= ~NVQ;
2224 deviceExtension->HwFlags = ChipFlags;
2225 }
2226 if(ChipFlags & NVQ) {
2227 /* disable ECO 398 */
2228 ChangePciConfig1(0x7f, (a & ~(1 << 7)));
2229
2230 KdPrint2((PRINT_PREFIX "Enable NCQ\n"));
2231 /* enable NCQ support */
2232 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400,
2233 tmp32 | ~0x00000006);
2234
2235 /* clear interrupt status */
2236 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0x00ff00ff);
2237 /* enable device and PHY state change interrupts */
2238 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 0x000d000d);
2239 } else {
2240 /* clear interrupt status */
2241 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0xff);
2242 /* enable device and PHY state change interrupts */
2243 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 0xdd);
2244 }
2245 /* enable PCI interrupt */
2246 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
2247 } else {
2248 //UniataSataPhyEnable(HwDeviceExtension, c);
2249 }
2250 } else {
2251 //UCHAR reg52;
2252
2253 if(c == CHAN_NOT_SPECIFIED) {
2254 /* set prefetch, postwrite */
2255 ChangePciConfig1(0x51, (a & 0x0f));
2256 } else {
2257 // check 80-pin cable
2258 generic_cable80(deviceExtension, channel, 0x52, 1);
2259 /* chan = &deviceExtension->chan[c];
2260 GetPciConfig1(0x52, reg52);
2261 if( !((reg52 >> (channel*2)) & 0x01)) {
2262 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2263 }*/
2264 }
2265 }
2266 break; }
2267 case ATA_PROMISE_ID: {
2268 USHORT Reg50;
2269 switch(ChipType) {
2270 case PRNEW:
2271 /* setup clocks */
2272 if(c == CHAN_NOT_SPECIFIED) {
2273 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
2274 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
2275 AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) | 0x0a );
2276 }
2277 /* FALLTHROUGH */
2278 case PROLD:
2279 /* enable burst mode */
2280 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
2281 if(c == CHAN_NOT_SPECIFIED) {
2282 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1f,
2283 AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1f) | 0x01 );
2284 } else {
2285 // check 80-pin cable
2286 chan = &deviceExtension->chan[c];
2287 GetPciConfig2(0x50, Reg50);
2288 if(Reg50 & (1 << (channel+10))) {
2289 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2290 }
2291 }
2292 break;
2293 case PRTX:
2294 if(c == CHAN_NOT_SPECIFIED) {
2295 // do nothing
2296 } else {
2297 // check 80-pin cable
2298 chan = &deviceExtension->chan[c];
2299 AtapiWritePort1(chan, IDX_BM_DeviceSpecific0, 0x0b);
2300 if(AtapiReadPort1(chan, IDX_BM_DeviceSpecific1) & 0x04) {
2301 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2302 }
2303 }
2304 break;
2305 case PRMIO:
2306 if(c == CHAN_NOT_SPECIFIED) {
2307 /* clear SATA status and unmask interrupts */
2308 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),
2309 (ChipFlags & PRG2) ? 0x60 : 0x6c, 0x000000ff);
2310 if(ChipFlags & UNIATA_SATA) {
2311 /* enable "long burst length" on gen2 chips */
2312 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), 0x44,
2313 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), 0x44) | 0x2000);
2314 }
2315 } else {
2316 chan = &deviceExtension->chan[c];
2317 AtapiWritePort4(chan, IDX_BM_Command,
2318 (AtapiReadPort4(chan, IDX_BM_Command) & ~0x00000f8f) | channel );
2319 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
2320 // check 80-pin cable
2321 if(chan->MaxTransferMode < ATA_SA150 &&
2322 (AtapiReadPort4(chan, IDX_BM_Command) & 0x01000000)) {
2323 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2324 }
2325 }
2326 break;
2327 }
2328 break; }
2329 case ATA_SERVERWORKS_ID:
2330 if(c == CHAN_NOT_SPECIFIED) {
2331 if(ChipType == SWKS33) {
2332 AtapiRosbSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
2333 SystemIoBusNumber, slotNumber);
2334 } else {
2335 ChangePciConfig1(0x5a, ((a & ~0x40) | ((ChipType == SWKS100) ? 0x03 : 0x02)));
2336 }
2337 }
2338 break;
2339 case ATA_ATI_ID:
2340 if(ChipType == SIIMIO) {
2341 KdPrint2((PRINT_PREFIX "ATI New\n"));
2342 // fall to SiI
2343 } else {
2344 KdPrint2((PRINT_PREFIX "ATI\n"));
2345 break;
2346 }
2347 /* FALLTHROUGH */
2348 case ATA_SILICON_IMAGE_ID:
2349 /* if(ChipFlags & SIIENINTR) {
2350 SetPciConfig1(0x71, 0x01);
2351 }*/
2352 switch(ChipType) {
2353 case SIIMIO: {
2354
2355 KdPrint2((PRINT_PREFIX "SII\n"));
2356 USHORT Reg79;
2357
2358 if(c == CHAN_NOT_SPECIFIED) {
2359 if(ChipFlags & SIISETCLK) {
2360 KdPrint2((PRINT_PREFIX "SIISETCLK\n"));
2361 GetPciConfig1(0x8a, tmp8);
2362 if ((tmp8 & 0x30) != 0x10)
2363 ChangePciConfig1(0x8a, (a & 0xcf) | 0x10);
2364 GetPciConfig1(0x8a, tmp8);
2365 if ((tmp8 & 0x30) != 0x10) {
2366 KdPrint2((PRINT_PREFIX "Sil 0680 could not set ATA133 clock\n"));
2367 deviceExtension->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
2368 }
2369 }
2370 }
2371 if(deviceExtension->MaxTransferMode < ATA_SA150) {
2372 // check 80-pin cable
2373 if(c == CHAN_NOT_SPECIFIED) {
2374 // do nothing
2375 } else {
2376 KdPrint2((PRINT_PREFIX "Check UDMA66 cable\n"));
2377 chan = &deviceExtension->chan[c];
2378 GetPciConfig2(0x79, Reg79);
2379 if(Reg79 & (channel ? 0x02 : 0x01)) {
2380 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2381 }
2382 }
2383 } else {
2384 ULONG unit01 = (c & 1);
2385 ULONG unit10 = (c & 2);
2386 /* enable/disable PHY state change interrupt */
2387 if(c == CHAN_NOT_SPECIFIED) {
2388 for(c=0; c<deviceExtension->NumberChannels; c++) {
2389 unit01 = (c & 1);
2390 unit10 = (c & 2);
2391 if(ChipFlags & SIINOSATAIRQ) {
2392 KdPrint2((PRINT_PREFIX "Disable broken SATA intr on c=%x\n", c));
2393 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),0);
2394 }
2395 }
2396 } else {
2397 if(ChipFlags & SIINOSATAIRQ) {
2398 KdPrint2((PRINT_PREFIX "Disable broken SATA intr on c=%x\n", c));
2399 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),0);
2400 } else {
2401 KdPrint2((PRINT_PREFIX "Enable SATA intr on c=%x\n", c));
2402 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16));
2403 }
2404 }
2405 }
2406 if(c == CHAN_NOT_SPECIFIED) {
2407 /* enable interrupt as BIOS might not */
2408 ChangePciConfig1(0x8a, (a & 0x3f));
2409 // Enable 3rd and 4th channels
2410 if (ChipFlags & SII4CH) {
2411 KdPrint2((PRINT_PREFIX "SII4CH\n"));
2412 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0200, 0x00000002);
2413 }
2414 } else {
2415 chan = &deviceExtension->chan[c];
2416 /* dont block interrupts */
2417 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2418 /*tmp32 =*/ AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48);
2419 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48, (1 << 22) << c);
2420 // flush
2421 /*tmp32 =*/ AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48);
2422
2423 /* Initialize FIFO PCI bus arbitration */
2424 GetPciConfig1(offsetof(PCI_COMMON_CONFIG, CacheLineSize), tmp8);
2425 if(tmp8) {
2426 KdPrint2((PRINT_PREFIX "SII: CacheLine=%d\n", tmp8));
2427 tmp8 = (tmp8/8)+1;
2428 AtapiWritePort2(chan, IDX_BM_DeviceSpecific1, ((USHORT)tmp8) << 8 | tmp8);
2429 } else {
2430 KdPrint2((PRINT_PREFIX "SII: CacheLine=0 !!!\n"));
2431 }
2432 }
2433 break; }
2434
2435 case SIICMD: {
2436
2437 KdPrint2((PRINT_PREFIX "SII_CMD\n"));
2438 if(c == CHAN_NOT_SPECIFIED) {
2439 /* Setup interrupts. */
2440 SetPciConfig1(0x71, 0x01);
2441
2442 /* GetPciConfig1(0x8a, tmp8);
2443 tmp8 &= ~(0x30);
2444 SetPciConfig1(0x71, tmp8);*/
2445
2446 /* Use MEMORY READ LINE for reads.
2447 * NOTE: Although not mentioned in the PCI0646U specs,
2448 * these bits are write only and won't be read
2449 * back as set or not. The PCI0646U2 specs clarify
2450 * this point.
2451 */
2452 /* tmp8 |= 0x02;
2453 SetPciConfig1(0x71, tmp8);
2454 */
2455 /* Set reasonable active/recovery/address-setup values. */
2456 SetPciConfig1(0x53, 0x40);
2457 SetPciConfig1(0x54, 0x3f);
2458 SetPciConfig1(0x55, 0x40);
2459 SetPciConfig1(0x56, 0x3f);
2460 SetPciConfig1(0x57, 0x1c);
2461 SetPciConfig1(0x58, 0x3f);
2462 SetPciConfig1(0x5b, 0x3f);
2463 }
2464
2465 break; }
2466 case ATI700:
2467 KdPrint2((PRINT_PREFIX "ATI700\n"));
2468 if(c == 0 && !(ChipFlags & UNIATA_AHCI)) {
2469 KdPrint2((PRINT_PREFIX "IXP700 PATA\n"));
2470 chan = &deviceExtension->chan[c];
2471 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
2472 }
2473 break;
2474 } /* switch(ChipType) */
2475 break;
2476 case ATA_SIS_ID:
2477 if(c == CHAN_NOT_SPECIFIED) {
2478 switch(ChipType) {
2479 case SIS33:
2480 break;
2481 case SIS66:
2482 case SIS100OLD:
2483 ChangePciConfig1(0x52, (a & ~0x04));
2484 break;
2485 case SIS100NEW:
2486 case SIS133OLD:
2487 ChangePciConfig1(0x49, (a & ~0x01));
2488 break;
2489 case SIS133NEW:
2490 ChangePciConfig2(0x50, (a | 0x0008));
2491 ChangePciConfig2(0x52, (a | 0x0008));
2492 break;
2493 case SISSATA:
2494 ChangePciConfig2(0x04, (a & ~0x0400));
2495 break;
2496 }
2497 }
2498 if(deviceExtension->HwFlags & UNIATA_SATA) {
2499 // do nothing for SATA
2500 } else
2501 if(ChipType == SIS133NEW) {
2502 // check 80-pin cable
2503 if(c == CHAN_NOT_SPECIFIED) {
2504 // do nothing
2505 } else {
2506 chan = &deviceExtension->chan[c];
2507 GetPciConfig2(channel ? 0x52 : 0x50, tmp16);
2508 if(tmp16 & 0x8000) {
2509 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2510 }
2511 }
2512 } else {
2513 // check 80-pin cable
2514 if(c == CHAN_NOT_SPECIFIED) {
2515 // do nothing
2516 } else {
2517 chan = &deviceExtension->chan[c];
2518 GetPciConfig1(48, tmp8);
2519 if(tmp8 & (0x10 << channel)) {
2520 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2521 }
2522 }
2523 }
2524 break;
2525 case ATA_VIA_ID:
2526
2527 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2528 break;
2529 }*/
2530 if(c == CHAN_NOT_SPECIFIED) {
2531 /* prepare for ATA-66 on the 82C686a and 82C596b */
2532 if(ChipFlags & VIACLK) {
2533 ChangePciConfig4(0x50, (a | 0x030b030b));
2534 }
2535 // no init for SATA
2536 if(ChipFlags & (UNIATA_SATA | VIASATA)) {
2537 /* enable PCI interrupt */
2538 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
2539
2540 /*
2541 * vt6420/1 has problems talking to some drives. The following
2542 * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
2543 *
2544 * When host issues HOLD, device may send up to 20DW of data
2545 * before acknowledging it with HOLDA and the host should be
2546 * able to buffer them in FIFO. Unfortunately, some WD drives
2547 * send upto 40DW before acknowledging HOLD and, in the
2548 * default configuration, this ends up overflowing vt6421's
2549 * FIFO, making the controller abort the transaction with
2550 * R_ERR.
2551 *
2552 * Rx52[2] is the internal 128DW FIFO Flow control watermark
2553 * adjusting mechanism enable bit and the default value 0
2554 * means host will issue HOLD to device when the left FIFO
2555 * size goes below 32DW. Setting it to 1 makes the watermark
2556 * 64DW.
2557 *
2558 * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
2559 */
2560
2561 if(DeviceID == 0x3149 || DeviceID == 0x3249) { //vt6420 or vt6421
2562 KdPrint2((PRINT_PREFIX "VIA 642x FIFO\n"));
2563 ChangePciConfig1(0x52, a | (1 << 2));
2564 }
2565
2566 break;
2567 }
2568
2569 /* the southbridge might need the data corruption fix */
2570 if(ChipFlags & VIABUG) {
2571 AtapiViaSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
2572 SystemIoBusNumber, slotNumber);
2573 }
2574 /* set prefetch, postwrite */
2575 if(ChipType != VIA133) {
2576 ChangePciConfig1(0x41, (a | 0xf0));
2577 }
2578
2579 /* set fifo configuration half'n'half */
2580 ChangePciConfig1(0x43, ((a & ((ChipFlags & VIAPRQ) ? 0x80 : 0x90)) | 0x2a));
2581
2582 /* set status register read retry */
2583 ChangePciConfig1(0x44, (a | 0x08));
2584
2585 /* set DMA read & end-of-sector fifo flush */
2586 ChangePciConfig1(0x46, ((a & 0x0c) | 0xf0));
2587
2588 /* set sector size */
2589 SetPciConfig2(0x60, DEV_BSIZE);
2590 SetPciConfig2(0x68, DEV_BSIZE);
2591 } else {
2592
2593 chan = &deviceExtension->chan[c];
2594 // no init for SATA
2595 if(ChipFlags & (UNIATA_SATA | VIASATA)) {
2596 if((ChipFlags & VIABAR) && (c >= 2)) {
2597 // this is PATA channel
2598 chan->MaxTransferMode = ATA_UDMA5;
2599 break;
2600 }
2601 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
2602 break;
2603 }
2604 /*
2605 // check 80-pin cable
2606 if(!via_cable80(deviceExtension, channel)) {
2607 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2608 }
2609 */
2610 }
2611
2612 break;
2613
2614 case ATA_ITE_ID:
2615 if(ChipType == ITE_33 || ChipType == ITE_133_NEW) {
2616 break;
2617 }
2618 if(ChipType == ITE_133) {
2619 if(c == CHAN_NOT_SPECIFIED) {
2620 /* set PCI mode and 66Mhz reference clock */
2621 ChangePciConfig1(0x50, a & ~0x83);
2622
2623 /* set default active & recover timings */
2624 SetPciConfig1(0x54, 0x31);
2625 SetPciConfig1(0x56, 0x31);
2626 } else {
2627 // check 80-pin cable
2628 GetPciConfig2(0x40, tmp16);
2629 chan = &deviceExtension->chan[c];
2630 if(!(tmp16 & (channel ? 0x08 : 0x04))) {
2631 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2632 }
2633 }
2634 } else
2635 if(ChipType == ITE_133_NEW) {
2636 }
2637 break;
2638 case ATA_CYRIX_ID:
2639 KdPrint2((PRINT_PREFIX "Cyrix\n"));
2640 if(ChipType == CYRIX_OLD) {
2641 if(c == CHAN_NOT_SPECIFIED) {
2642 GetPciConfig1(0x60, tmp8);
2643 if(!(tmp8 & 0x40)) {
2644 KdPrint2((PRINT_PREFIX "Enable DMA\n"));
2645 tmp8 |= 0x40;
2646 SetPciConfig1(0x60, tmp8);
2647 }
2648 }
2649 }
2650 break;
2651 default:
2652 if(c != CHAN_NOT_SPECIFIED) {
2653 // We don't know how to check for 80-pin cable on unknown controllers.
2654 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2655 // So, leave this flag to use as hint in error recovery procedures
2656 KdPrint2((PRINT_PREFIX "UNIATA_NO80CHK\n"));
2657 deviceExtension->HwFlags |= UNIATA_NO80CHK;
2658 }
2659 break;
2660 }
2661
2662 // In all places separate channels are inited after common controller init
2663 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2664 if(CheckCable && !(ChipFlags & (UNIATA_NO80CHK | UNIATA_SATA))) {
2665 for(c=0; c<deviceExtension->NumberChannels; c++) {
2666 AtapiChipInit(HwDeviceExtension, DeviceNumber, c);
2667 }
2668 }
2669
2670 return TRUE;
2671 } // end AtapiChipInit()
2672
2673 VOID
2674 NTAPI
2675 UniataInitMapBM(
2676 IN PHW_DEVICE_EXTENSION deviceExtension,
2677 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0,
2678 IN BOOLEAN MemIo
2679 )
2680 {
2681 PHW_CHANNEL chan;
2682 ULONG c;
2683 ULONG i;
2684
2685 if(!BaseIoAddressBM_0) {
2686 MemIo = FALSE;
2687 }
2688 for(c=0; c<deviceExtension->NumberChannels; c++) {
2689 chan = &deviceExtension->chan[c];
2690 for (i=0; i<IDX_BM_IO_SZ; i++) {
2691 UniataInitIoRes(chan, IDX_BM_IO+i, BaseIoAddressBM_0 ? ((ULONGIO_PTR)BaseIoAddressBM_0 + i) : 0, MemIo, FALSE);
2692 }
2693 if(BaseIoAddressBM_0) {
2694 BaseIoAddressBM_0++;
2695 }
2696 }
2697 return;
2698 } // end UniataInitMapBM()
2699
2700 VOID
2701 NTAPI
2702 UniataInitMapBase(
2703 IN PHW_CHANNEL chan,
2704 IN PIDE_REGISTERS_1 BaseIoAddress1,
2705 IN PIDE_REGISTERS_2 BaseIoAddress2
2706 )
2707 {
2708 ULONG i;
2709
2710 for (i=0; i<IDX_IO1_SZ; i++) {
2711 UniataInitIoRes(chan, IDX_IO1+i, BaseIoAddress1 ? ((ULONGIO_PTR)BaseIoAddress1 + i) : 0, FALSE, FALSE);
2712 }
2713 for (i=0; i<IDX_IO2_SZ; i++) {
2714 UniataInitIoRes(chan, IDX_IO2+i, BaseIoAddress2 ? ((ULONGIO_PTR)BaseIoAddress2 + i) : 0, FALSE, FALSE);
2715 }
2716 UniataInitSyncBaseIO(chan);
2717 return;
2718 } // end UniataInitMapBase()
2719
2720 VOID
2721 NTAPI
2722 UniataInitSyncBaseIO(
2723 IN PHW_CHANNEL chan
2724 )
2725 {
2726 RtlCopyMemory(&chan->RegTranslation[IDX_IO1_o], &chan->RegTranslation[IDX_IO1], IDX_IO1_SZ*sizeof(chan->RegTranslation[0]));
2727 RtlCopyMemory(&chan->RegTranslation[IDX_IO2_o], &chan->RegTranslation[IDX_IO2], IDX_IO2_SZ*sizeof(chan->RegTranslation[0]));
2728 return;
2729 } // end UniataInitSyncBaseIO()
2730
2731 VOID
2732 UniataInitIoRes(
2733 IN PHW_CHANNEL chan,
2734 IN ULONG idx,
2735 IN ULONG addr,
2736 IN BOOLEAN MemIo,
2737 IN BOOLEAN Proc
2738 )
2739 {
2740 if(!addr) {
2741 MemIo = Proc = FALSE;
2742 }
2743 chan->RegTranslation[idx].Addr = addr;
2744 chan->RegTranslation[idx].MemIo = MemIo;
2745 chan->RegTranslation[idx].Proc = Proc;
2746 } // end UniataInitIoRes()
2747
2748 VOID
2749 UniataInitIoResEx(
2750 IN PIORES IoRes,
2751 IN ULONG addr,
2752 IN BOOLEAN MemIo,
2753 IN BOOLEAN Proc
2754 )
2755 {
2756 if(!addr) {
2757 MemIo = Proc = FALSE;
2758 }
2759 IoRes->Addr = addr;
2760 IoRes->MemIo = MemIo;
2761 IoRes->Proc = Proc;
2762 } // end UniataInitIoResEx()
2763
2764 VOID
2765 NTAPI
2766 AtapiSetupLunPtrs(
2767 IN PHW_CHANNEL chan,
2768 IN PHW_DEVICE_EXTENSION deviceExtension,
2769 IN ULONG c
2770 )
2771 {
2772 ULONG i;
2773
2774 KdPrint2((PRINT_PREFIX "AtapiSetupLunPtrs for channel %d of %d, %d luns \n", c, deviceExtension->NumberChannels, deviceExtension->NumberLuns));
2775
2776 if(!deviceExtension->NumberLuns) {
2777 KdPrint2((PRINT_PREFIX "Achtung !deviceExtension->NumberLuns \n"));
2778 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN;
2779 }
2780 KdPrint2((PRINT_PREFIX " Chan %#x\n", chan));
2781 chan->DeviceExtension = deviceExtension;
2782 chan->lChannel = c;
2783 chan->NumberLuns = deviceExtension->NumberLuns;
2784 for(i=0; i<deviceExtension->NumberLuns; i++) {
2785 chan->lun[i] = &(deviceExtension->lun[c*deviceExtension->NumberLuns+i]);
2786 KdPrint2((PRINT_PREFIX " Lun %#x\n", i));
2787 KdPrint2((PRINT_PREFIX " Lun ptr %#x\n", chan->lun[i]));
2788 }
2789 chan->AltRegMap = deviceExtension->AltRegMap;
2790 chan->NextDpcChan = -1;
2791 chan->last_devsel = -1;
2792 for(i=0; i<deviceExtension->NumberLuns; i++) {
2793 chan->lun[i]->DeviceExtension = deviceExtension;
2794 chan->lun[i]->chan = chan;
2795 chan->lun[i]->Lun = i;
2796 }
2797 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
2798 deviceExtension->AhciInternalAtaReq0 &&
2799 deviceExtension->AhciInternalSrb0) {
2800 chan->AhciInternalAtaReq = &(deviceExtension->AhciInternalAtaReq0[c]);
2801 chan->AhciInternalSrb = &(deviceExtension->AhciInternalSrb0[c]);
2802 UniataAhciSetupCmdPtr(chan->AhciInternalAtaReq);
2803 chan->AhciInternalSrb->SrbExtension = chan->AhciInternalAtaReq;
2804 chan->AhciInternalAtaReq->Srb = chan->AhciInternalSrb;
2805 }
2806 return;
2807 } // end AtapiSetupLunPtrs()
2808
2809 BOOLEAN
2810 NTAPI
2811 UniataAllocateLunExt(
2812 PHW_DEVICE_EXTENSION deviceExtension,
2813 ULONG NewNumberChannels
2814 )
2815 {
2816 PHW_LU_EXTENSION old_luns = NULL;
2817 PHW_CHANNEL old_chans = NULL;
2818
2819 KdPrint2((PRINT_PREFIX "allocate %d Luns for %d channels\n", deviceExtension->NumberLuns, deviceExtension->NumberChannels));
2820
2821 old_luns = deviceExtension->lun;
2822 old_chans = deviceExtension->chan;
2823
2824 if(old_luns || old_chans) {
2825 if(NewNumberChannels == UNIATA_ALLOCATE_NEW_LUNS) {
2826 KdPrint2((PRINT_PREFIX "already allocated!\n"));
2827 return FALSE;
2828 }
2829 }
2830
2831 if(!deviceExtension->NumberLuns) {
2832 KdPrint2((PRINT_PREFIX "default NumberLuns=2\n"));
2833 deviceExtension->NumberLuns = 2;
2834 }
2835
2836 if(deviceExtension->HwFlags & UNIATA_AHCI) {
2837 if(!deviceExtension->AhciInternalAtaReq0) {
2838 deviceExtension->AhciInternalAtaReq0 = (PATA_REQ)ExAllocatePool(NonPagedPool, sizeof(ATA_REQ)*deviceExtension->NumberChannels);
2839 if (!deviceExtension->AhciInternalAtaReq0) {
2840 KdPrint2((PRINT_PREFIX "!deviceExtension->AhciInternalAtaReq0 => SP_RETURN_ERROR\n"));
2841 return FALSE;
2842 }
2843 RtlZeroMemory(deviceExtension->AhciInternalAtaReq0, sizeof(ATA_REQ)*deviceExtension->NumberChannels);
2844 }
2845 if(!deviceExtension->AhciInternalSrb0) {
2846 deviceExtension->AhciInternalSrb0 = (PSCSI_REQUEST_BLOCK)ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK)*deviceExtension->NumberChannels);
2847 if (!deviceExtension->AhciInternalSrb0) {
2848 KdPrint2((PRINT_PREFIX "!deviceExtension->AhciInternalSrb0 => SP_RETURN_ERROR\n"));
2849 UniataFreeLunExt(deviceExtension);
2850 return FALSE;
2851 }
2852 RtlZeroMemory(deviceExtension->AhciInternalSrb0, sizeof(SCSI_REQUEST_BLOCK)*deviceExtension->NumberChannels);
2853 }
2854 }
2855
2856 deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
2857 if (!deviceExtension->lun) {
2858 KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
2859 UniataFreeLunExt(deviceExtension);
2860 return FALSE;
2861 }
2862 RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
2863
2864 deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
2865 if (!deviceExtension->chan) {
2866 UniataFreeLunExt(deviceExtension);
2867 KdPrint2((PRINT_PREFIX "!deviceExtension->chan => SP_RETURN_ERROR\n"));
2868 return FALSE;
2869 }
2870 RtlZeroMemory(deviceExtension->chan, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
2871 return TRUE;
2872 } // end UniataAllocateLunExt()
2873
2874 VOID
2875 NTAPI
2876 UniataFreeLunExt(
2877 PHW_DEVICE_EXTENSION deviceExtension
2878 )
2879 {
2880 if (deviceExtension->lun) {
2881 ExFreePool(deviceExtension->lun);
2882 deviceExtension->lun = NULL;
2883 }
2884 if (deviceExtension->chan) {
2885 ExFreePool(deviceExtension->chan);
2886 deviceExtension->chan = NULL;
2887 }
2888 if(deviceExtension->AhciInternalAtaReq0) {
2889 ExFreePool(deviceExtension->AhciInternalAtaReq0);
2890 deviceExtension->AhciInternalAtaReq0 = NULL;
2891 }
2892 if(deviceExtension->AhciInternalSrb0) {
2893 ExFreePool(deviceExtension->AhciInternalSrb0);
2894 deviceExtension->AhciInternalSrb0 = NULL;
2895 }
2896
2897 return;
2898 } // end UniataFreeLunExt()
2899