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