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