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