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