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