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