3 Copyright (c) 2004-2012 Alexandr A. Telyatnikov (Alter)
9 This is the chip-specific init module for ATA/ATAPI IDE controllers
10 with Busmaster DMA and Serial ATA support
13 Alexander A. Telyatnikov (Alter)
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 Some parts of code were taken from FreeBSD 5.1-6.1 ATA driver by
34 Søren Schmidt, Copyright (c) 1998-2007
35 added IT8172 IDE controller support from Linux
36 added VIA 8233/8235 fix from Linux
37 added 80-pin cable detection from Linux for
39 added support for non-standard layout of registers
46 static BUSMASTER_CONTROLLER_INFORMATION
const AtiSouthAdapters
[] = {
47 PCI_DEV_HW_SPEC_BM( 4385, 1002, 0x00, ATA_MODE_NOT_SPEC
, "ATI South", 0 ),
48 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
54 UniataChipDetectChannels(
55 IN PVOID HwDeviceExtension
,
56 IN PPCI_COMMON_CONFIG pciData
, // optional
57 IN ULONG DeviceNumber
,
58 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
61 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
62 //ULONG slotNumber = deviceExtension->slotNumber;
63 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
64 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
65 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
66 //ULONG RevID = deviceExtension->RevID;
67 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
68 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
70 KdPrint2((PRINT_PREFIX
"UniataChipDetectChannels:\n" ));
72 if(ChipFlags
& (UNIATA_SATA
| UNIATA_AHCI
)) {
73 if(!deviceExtension
->NumberChannels
) {
74 KdPrint2((PRINT_PREFIX
"uninitialized SATA/AHCI port number -> 1\n"));
75 deviceExtension
->NumberChannels
= 1;
77 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhciPM", 1 /* DEBUG */)) {
78 KdPrint2((PRINT_PREFIX
"SATA/AHCI w/o PM, max luns 1 or 2\n"));
79 deviceExtension
->NumberLuns
= 2; // we may be in Legacy mode
80 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
82 KdPrint2((PRINT_PREFIX
"SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS
));
83 deviceExtension
->NumberLuns
= SATA_MAX_PM_UNITS
;
84 //deviceExtension->NumberLuns = 1;
87 if(deviceExtension
->MasterDev
) {
88 KdPrint2((PRINT_PREFIX
"MasterDev -> 1 chan\n"));
89 deviceExtension
->NumberChannels
= 1;
93 case ATA_ACER_LABS_ID
:
94 switch(deviceExtension
->DevID
) {
97 deviceExtension
->NumberChannels
= 4;
98 KdPrint2((PRINT_PREFIX
"Acer 4 chan\n"));
103 if(ChipType
!= PRMIO
) {
106 if(!(ChipFlags
& UNIATA_SATA
)) {
107 deviceExtension
->NumberChannels
= 4;
108 KdPrint2((PRINT_PREFIX
"Promise up to 4 chan\n"));
110 if(ChipFlags
& PRCMBO
) {
111 deviceExtension
->NumberChannels
= 3;
112 KdPrint2((PRINT_PREFIX
"Promise 3 chan\n"));
114 deviceExtension
->NumberChannels
= 4;
115 KdPrint2((PRINT_PREFIX
"Promise 4 chan\n"));
119 KdPrint2((PRINT_PREFIX
"Marvell\n"));
120 /* AHCI part has own DevID-based workaround */
121 switch(deviceExtension
->DevID
) {
123 /* 88SX6101 only have 1 PATA channel */
124 if(BMList
[deviceExtension
->DevIndex
].channel
) {
125 KdPrint2((PRINT_PREFIX
"88SX6101/11 has no 2nd PATA chan\n"));
128 deviceExtension
->NumberChannels
= 1;
129 KdPrint2((PRINT_PREFIX
"88SX6101 PATA 1 chan\n"));
134 KdPrint2((PRINT_PREFIX
"ATI\n"));
135 switch(deviceExtension
->DevID
) {
137 KdPrint2((PRINT_PREFIX
" IXP600\n"));
138 /* IXP600 only have 1 PATA channel */
139 if(BMList
[deviceExtension
->DevIndex
].channel
) {
140 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
143 deviceExtension
->NumberChannels
= 1;
144 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
147 case ATA_ATI_IXP700
: {
149 PCI_SLOT_NUMBER slotData
;
152 KdPrint2((PRINT_PREFIX
" IXP700\n"));
154 * When "combined mode" is enabled, an additional PATA channel is
155 * emulated with two SATA ports and appears on this device.
156 * This mode can only be detected via SMB controller.
158 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&AtiSouthAdapters
[0], -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, &slotData
);
159 if(i
!= BMLIST_TERMINATOR
) {
160 slotNumber
= slotData
.u
.AsULONG
;
162 GetPciConfig1(0xad, satacfg
);
163 KdPrint(("SATA controller %s (%s%s channel)\n",
164 (satacfg
& 0x01) == 0 ? "disabled" : "enabled",
165 (satacfg
& 0x08) == 0 ? "" : "combined mode, ",
166 (satacfg
& 0x10) == 0 ? "primary" : "secondary"));
168 * If SATA controller is enabled but combined mode is disabled,
169 * we have only one PATA channel. Ignore a non-existent channel.
171 if ((satacfg
& 0x09) == 0x01) {
172 if(BMList
[deviceExtension
->DevIndex
].channel
) {
173 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
176 deviceExtension
->NumberChannels
= 1;
177 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
180 KdPrint2((PRINT_PREFIX
"New ATI 2 chan\n"));
181 deviceExtension
->NumberChannels
= 2;
183 if (BMList[deviceExtension->DevIndex].channel != ((satacfg & 0x10) >> 4)) {
194 case ATA_SILICON_IMAGE_ID
:
196 if(ChipFlags
& SIIBUG
) {
197 /* work around errata in early chips */
198 deviceExtension
->DmaSegmentLength
= 15 * DEV_BSIZE
;
199 deviceExtension
->DmaSegmentAlignmentMask
= 8192-1;
201 if(ChipType
!= SIIMIO
) {
208 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
209 KdPrint2((PRINT_PREFIX
"New SII\n"));
211 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
213 if(deviceExtension
->HwFlags
& SII4CH
) {
214 deviceExtension
->NumberChannels
= 4;
215 KdPrint2((PRINT_PREFIX
"4 chan\n"));
219 if(/*(deviceExtension->DevID == 0x32491106) &&
220 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)*/
221 deviceExtension
->HwFlags
& VIABAR
) {
222 deviceExtension
->NumberChannels
= 3;
223 KdPrint2((PRINT_PREFIX
"VIA 3 chan\n"));
225 if(ChipFlags
& VIASATA
) {
226 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
227 // do nothing, generic PATA INIT
228 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs -> no PM\n"));
229 deviceExtension
->NumberLuns
= 1;
233 /* ITE ATA133 controller */
234 if(deviceExtension
->DevID
== 0x82131283) {
235 if(BMList
[deviceExtension
->DevIndex
].channel
) {
236 KdPrint2((PRINT_PREFIX
"New ITE has no 2nd PATA chan\n"));
239 deviceExtension
->NumberChannels
= 1;
240 KdPrint2((PRINT_PREFIX
"New ITE PATA 1 chan\n"));
245 /* New Intel PATA controllers */
246 if(g_opt_VirtualMachine
!= VM_VBOX
&&
247 /*deviceExtension->DevID == 0x27df8086 ||
248 deviceExtension->DevID == 0x269e8086 ||
249 deviceExtension->DevID == ATA_I82801HBM*/
251 if(BMList
[deviceExtension
->DevIndex
].channel
) {
252 KdPrint2((PRINT_PREFIX
"New Intel PATA has no 2nd chan\n"));
255 deviceExtension
->NumberChannels
= 1;
256 KdPrint2((PRINT_PREFIX
"New Intel PATA 1 chan\n"));
259 #endif // this code is removed from newer FreeBSD
261 /* New JMicron PATA controllers */
262 if(deviceExtension
->DevID
== ATA_JMB361
||
263 deviceExtension
->DevID
== ATA_JMB363
||
264 deviceExtension
->DevID
== ATA_JMB368
) {
265 if(BMList
[deviceExtension
->DevIndex
].channel
) {
266 KdPrint2((PRINT_PREFIX
"New JMicron has no 2nd chan\n"));
269 deviceExtension
->NumberChannels
= 1;
270 KdPrint2((PRINT_PREFIX
"New JMicron PATA 1 chan\n"));
273 } // end switch(VendorID)
276 } // end UniataChipDetectChannels()
281 IN PVOID HwDeviceExtension
,
282 IN PPCI_COMMON_CONFIG pciData
, // optional
283 IN ULONG DeviceNumber
,
284 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
285 IN BOOLEAN
* simplexOnly
288 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
289 ULONG slotNumber
= deviceExtension
->slotNumber
;
290 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
291 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
292 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
293 ULONG RevID
= deviceExtension
->RevID
;
295 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
301 ULONG BaseMemAddress
;
302 ULONG BaseIoAddress1
;
303 ULONG BaseIoAddress2
;
304 ULONG BaseIoAddressBM
;
305 BOOLEAN MemIo
= FALSE
;
306 BOOLEAN IsPata
= FALSE
;
308 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
309 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
311 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
313 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
319 BaseIoAddressBM
= pciData
->u
.type0
.BaseAddresses
[4] & ~0x07;
320 deviceExtension
->MaxTransferMode
= BaseIoAddressBM
? ATA_DMA
: ATA_PIO4
;
321 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
322 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
323 //deviceExtension->NumberOfPhysicalBreaks = min(deviceExtension->MaximumDmaTransferLength/PAGE_SIZE+1, ATA_DMA_ENTRIES);
324 deviceExtension
->DmaSegmentLength
= 0x10000;
325 deviceExtension
->DmaSegmentAlignmentMask
= 0xffff;
327 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
328 if(i
!= BMLIST_TERMINATOR
) {
329 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
332 if(Ata_is_ahci_dev(pciData
)) {
333 KdPrint2((PRINT_PREFIX
" AHCI candidate"));
335 deviceExtension
->NumberChannels
= 0;
336 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
337 KdPrint2((PRINT_PREFIX
" AHCI init failed - not detected\n"));
338 return STATUS_UNSUCCESSFUL
;
340 KdPrint2((PRINT_PREFIX
" unknown AHCI dev, addr %#x ", deviceExtension
->BaseIoAHCI_0
.Addr
));
342 KdPrint2((PRINT_PREFIX
" unknown dev, BM addr %#x ", BaseIoAddressBM
));
344 KdPrint2((PRINT_PREFIX
" MaxTransferMode %#x\n", deviceExtension
->MaxTransferMode
));
346 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
347 return STATUS_UNSUCCESSFUL
;
349 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
350 return STATUS_UNSUCCESSFUL
;
352 // DEBUG, we shall return success when AHCI is completly supported
353 //return STATUS_NOT_FOUND;
354 return STATUS_SUCCESS
;
357 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
358 PCI_DEV_HW_SPEC_BM( 1183, 1039, 0x00, ATA_SA150
, "SiS 1183 IDE" , SIS133NEW
),
359 PCI_DEV_HW_SPEC_BM( 1182, 1039, 0x00, ATA_SA150
, "SiS 1182" , SISSATA
| UNIATA_SATA
),
360 PCI_DEV_HW_SPEC_BM( 0183, 1039, 0x00, ATA_SA150
, "SiS 183 RAID" , SISSATA
| UNIATA_SATA
),
361 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
362 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
363 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
364 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
365 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
366 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
367 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
369 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
370 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
371 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
372 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
374 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
375 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),*/
376 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
377 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
378 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
379 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x30, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
380 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
381 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
383 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
384 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
385 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
387 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
388 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
390 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
391 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
392 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
393 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
394 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
395 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
398 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
399 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
400 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
401 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
402 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
403 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
404 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
405 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
406 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
407 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
408 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
409 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
410 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
411 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| 0x00 ),
412 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| 0x00 ),
413 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
414 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6
, "VIA 8237A" , VIA133
| 0x00 ),
415 // presence of AHCI controller means something about isa-mapped part
416 PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_UDMA6
, "VIA 8237S" , VIA133
| 0x00 ),
417 PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
418 PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
419 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8251" , VIA133
| 0x00 ),
420 PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150
, "VIA CX700" , VIA133
| VIASATA
),
421 PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150
, "VIA VX800" , VIA133
| VIASATA
),
422 PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6
, "VIA VX855" , VIA133
| 0x00 ),
423 PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300
, "VIA VX900" , VIA133
| VIASATA
),
424 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
427 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
428 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8361", VIASOUTH
),
429 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8363", VIASOUTH
),
430 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8371", VIASOUTH
),
431 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, ATA_MODE_NOT_SPEC
, "VIA 8662", VIASOUTH
),
432 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
435 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
441 We shall get here for all SIS controllers, even unlisted.
442 Then perform bus scan to find SIS bridge and decide what to do with controller
444 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
445 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
446 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
447 if(i
!= BMLIST_TERMINATOR
) {
448 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
453 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
454 // New chips have own DeviceId
455 if(deviceExtension
->DevID
!= ATA_VIA82C571
&&
456 deviceExtension
->DevID
!= ATA_VIACX700IDE
&&
457 deviceExtension
->DevID
!= ATA_VIASATAIDE
&&
458 deviceExtension
->DevID
!= ATA_VIASATAIDE2
&&
459 deviceExtension
->DevID
!= ATA_VIASATAIDE3
) {
460 KdPrint2((PRINT_PREFIX
"Via new\n"));
463 KdPrint2((PRINT_PREFIX
"Via-old-style %x\n", deviceExtension
->DevID
));
464 // Traditionally, chips have same DeviceId, we can distinguish between them
465 // only by ISA Bridge DeviceId
466 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
467 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
468 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
469 /* if(i == BMLIST_TERMINATOR) {
470 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
472 if(i
!= BMLIST_TERMINATOR
) {
473 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
474 deviceExtension
->HwFlags
|= VIASOUTH
;
476 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
477 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
478 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
479 if(i
!= BMLIST_TERMINATOR
) {
480 deviceExtension
->FullDevName
= ViaAdapters
[i
].FullDevName
;
490 KdPrint2((PRINT_PREFIX
"Default\n"));
492 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
493 /* do extra chipset specific setups */
494 switch(deviceExtension
->DevID
) {
496 //case ATA_CYPRESS_ID:
497 case 0xc6931080: /* 82c693 ATA controller */
498 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
501 case 0x000116ca: /* Cenatek Rocket Drive controller */
502 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
505 /* case ATA_CYRIX_ID:
506 DevTypeInfo = &CyrixAdapters[0];
508 case 0x01021078: /* Cyrix 5530 ATA33 controller */
509 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
512 case 0x06401039: /* CMD 640 known bad, no DMA */
518 case 0x10001042: /* RZ 100x known bad, no DMA */
521 if(deviceExtension
->BaseIoAddressBM_0
)
522 ScsiPortFreeDeviceBase(HwDeviceExtension
,
523 deviceExtension
->BaseIoAddressBM_0
);
525 deviceExtension
->BaseIoAddressBM_0
.Addr
= 0;
526 deviceExtension
->BaseIoAddressBM_0
.MemIo
= 0;
527 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
528 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
531 case 0x81721283: /* IT8172 IDE controller */
532 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
537 return STATUS_NOT_FOUND
;
539 return STATUS_SUCCESS
;
543 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
545 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
546 if(i
== BMLIST_TERMINATOR
) {
548 //return STATUS_NOT_FOUND;
550 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
551 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
553 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
555 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
556 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
557 deviceExtension
->HwFlags
= tmp32
;
559 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
560 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
561 deviceExtension
->HwFlags
|= tmp32
;
563 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
564 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
565 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
569 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
570 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
571 if(tmp32
!= 0xffffffff) {
572 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
573 deviceExtension
->MaxTransferMode
= tmp32
;
576 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
577 deviceExtension
->HwFlags
|= UNIATA_SATA
;
581 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
582 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
584 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
585 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
587 /* for even more ugly AHCI-capable chips */
588 if(ChipFlags
& UNIATA_AHCI
) {
590 Seems, some chips may have inoperable/alternative BAR5 in SATA mode
591 This can be detected via PCI SubClass
596 KdPrint2((PRINT_PREFIX
"ATA_xxx_ID check AHCI subclass\n"));
597 if((pciData
)->SubClass
== PCI_DEV_SUBCLASS_IDE
) {
598 KdPrint2((PRINT_PREFIX
"Non-AHCI mode\n"));
599 ChipFlags
&= ~UNIATA_AHCI
;
600 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
606 if(ChipFlags
& UNIATA_AHCI
) {
607 deviceExtension
->NumberChannels
= 0;
608 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
609 KdPrint2((PRINT_PREFIX
" AHCI detect failed\n"));
610 return STATUS_UNSUCCESSFUL
;
613 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
614 return STATUS_UNSUCCESSFUL
;
616 // UniataAhciDetect() sets proper number of channels
617 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
618 return STATUS_UNSUCCESSFUL
;
622 case ATA_ACER_LABS_ID
:
623 if(ChipFlags
& UNIATA_SATA
) {
624 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
625 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
627 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
629 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
630 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
631 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
632 //ULONG unit01 = (c & 1);
633 ULONG unit10
= (c
& 2);
634 chan
= &deviceExtension
->chan
[c
];
636 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
637 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
639 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
640 UniataInitSyncBaseIO(chan
);
642 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
643 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
646 // SATA not supported yet
648 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
649 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
650 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
652 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
657 if(ChipFlags
& UNIATA_SATA
) {
658 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
659 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
660 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
661 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
662 if(!BaseMemAddress
) {
663 return STATUS_UNSUCCESSFUL
;
665 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
666 KdPrint2((PRINT_PREFIX
"MemIo\n"));
669 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
670 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
671 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
672 chan
= &deviceExtension
->chan
[c
];
674 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
675 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
676 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
677 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
678 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
679 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
681 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
687 if(ChipType
!= PRMIO
) {
693 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
696 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
698 KdPrint2((PRINT_PREFIX
"BaseMemAddress[4] %x\n", BaseMemAddress
));
699 if(!BaseMemAddress
) {
700 return STATUS_UNSUCCESSFUL
;
702 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
703 KdPrint2((PRINT_PREFIX
"MemIo\n"));
706 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
707 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
710 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
712 KdPrint2((PRINT_PREFIX
"BaseMemAddress[3] %x\n", BaseMemAddress
));
713 if(!BaseMemAddress
) {
714 return STATUS_UNSUCCESSFUL
;
716 if((*ConfigInfo
->AccessRanges
)[3].RangeInMemory
) {
717 KdPrint2((PRINT_PREFIX
"MemIo\n"));
720 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
721 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
723 if(!(ChipFlags
& UNIATA_SATA
)) {
726 reg48
= AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
727 deviceExtension
->NumberChannels
= ((reg48
& 0x01) ? 1 : 0) +
728 ((reg48
& 0x02) ? 1 : 0) +
730 KdPrint2((PRINT_PREFIX
"Channels -> %d\n", deviceExtension
->NumberChannels
));
733 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
738 chan
= &deviceExtension
->chan
[c
];
743 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
744 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs7
;
745 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
747 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
748 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
750 UniataInitSyncBaseIO(chan
);
752 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
753 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
754 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
755 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
756 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
757 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
759 if((ChipFlags
& PRSATA
) ||
760 ((ChipFlags
& PRCMBO
) && c
<2)) {
761 KdPrint2((PRINT_PREFIX
"Promise SATA\n"));
763 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x400 + offs7
;
764 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
765 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x404 + offs7
;
766 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
767 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x408 + offs7
;
768 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
770 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
772 KdPrint2((PRINT_PREFIX
"Promise PATA\n"));
773 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA6
);
779 KdPrint2((PRINT_PREFIX
"ATI\n"));
780 if(ChipType
== ATI700
) {
781 KdPrint2((PRINT_PREFIX
"ATI700\n"));
782 if(!(ChipFlags
& UNIATA_AHCI
)) {
783 KdPrint2((PRINT_PREFIX
"IXP700 PATA\n"));
784 chan
= &deviceExtension
->chan
[0];
785 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
790 case ATA_SILICON_IMAGE_ID
: {
792 if(ChipFlags
& SIIBUG
) {
794 if(ChipType
!= SIIMIO
) {
801 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
802 KdPrint2((PRINT_PREFIX
"New SII\n"));
804 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
806 //if(deviceExtension->HwFlags & SII4CH) {
807 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
809 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
811 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
812 if(!BaseMemAddress
) {
813 return STATUS_UNSUCCESSFUL
;
815 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
816 KdPrint2((PRINT_PREFIX
"MemIo\n"));
819 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
820 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
822 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
823 ULONG unit01
= (c
& 1);
824 ULONG unit10
= (c
& 2);
826 chan
= &deviceExtension
->chan
[c
];
828 if(deviceExtension
->AltRegMap
) {
829 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
830 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
831 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
833 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
834 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
835 UniataInitSyncBaseIO(chan
);
837 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
838 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
839 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
840 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
841 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
842 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
843 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
844 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
845 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
846 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
847 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
848 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
851 if(chan
->MaxTransferMode
< ATA_SA150
) {
852 // do nothing for PATA part
853 KdPrint2((PRINT_PREFIX
"No SATA regs for PATA part\n"));
855 if(ChipFlags
& UNIATA_SATA
) {
856 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
857 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
858 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
859 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
860 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
861 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
863 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
868 case ATA_SERVERWORKS_ID
: {
870 if(ChipType
!= SWKSMIO
) {
877 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
879 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
880 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
882 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
883 if(!BaseMemAddress
) {
884 return STATUS_UNSUCCESSFUL
;
886 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
887 KdPrint2((PRINT_PREFIX
"MemIo\n"));
890 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
891 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
893 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
894 ULONG offs
= c
*0x100;
896 chan
= &deviceExtension
->chan
[c
];
897 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
898 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
899 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
901 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
902 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
903 UniataInitSyncBaseIO(chan
);
905 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
906 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
907 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
908 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
909 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
910 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
912 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
913 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
914 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
915 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
916 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
917 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
919 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
924 //if(ChipType != SIS_SOUTH) {}
925 BOOLEAN SIS_182
=FALSE
;
927 if(!(ChipFlags
& SIS_BASE
)) {
928 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
929 //PrintNtConsole("Found SIS_SOUTH\n");
932 // Make some additional checks
933 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
934 ChangePciConfig1(0x57, (a
& 0x7f));
935 GetPciConfig4(0x00, tmp32
);
936 if(tmp32
== ATA_SIS5518
) {
937 ChipType
= SIS133NEW
;
938 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
939 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
940 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
941 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
943 ChangePciConfig1(0x57, (a
| 0x80));
945 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
946 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, ATA_MODE_NOT_SPEC
, "SiS 961", 0 ),
947 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_MODE_NOT_SPEC, "SiS 961", 0 ),
948 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, ATA_MODE_NOT_SPEC
, NULL
, -1 )
951 GetPciConfig1(0x4a, tmp8
);
952 ChangePciConfig1(0x4a, (a
| 0x10));
953 if(tmp32
== ATA_SIS5513
||
954 tmp32
== ATA_SIS5517
) {
955 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
956 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
957 if(i
!= BMLIST_TERMINATOR
) {
958 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
959 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
960 //deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
961 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
962 deviceExtension
->HwFlags
|= UNIATA_SATA
;
963 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182 ||
964 SiSSouthAdapters
[i
].nDeviceId
== 0x1183) {
969 // SiS-South not found
970 if(tmp32
== ATA_SIS5517
) {
971 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
972 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
975 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
980 SetPciConfig1(0x4a, tmp8
);
981 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
982 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
983 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
984 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
986 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
988 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
990 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
991 KdPrint2((PRINT_PREFIX
"MemIo\n"));
994 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
995 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
997 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
998 ULONG offs
= c
<< (SIS_182
? 5 : 6);
1000 chan
= &deviceExtension
->chan
[c
];
1001 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
1002 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1003 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
1004 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1005 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
1006 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1008 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1013 //ChangePciConfig1(0x57, (a | 0x80));
1018 if(ChipFlags
& VIASATA
) {
1019 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
1020 // do nothing, generic PATA INIT
1021 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs\n"));
1024 if(ChipFlags
& UNIATA_SATA
) {
1027 ULONG BaseMemAddress
= 0;
1030 case 0x3149: // VIA 6420
1031 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
1034 case 0x3249: // VIA 6421
1035 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
1040 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
1041 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1042 5, 0, IoSize
* deviceExtension
->NumberChannels
);
1043 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1044 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1047 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1048 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1050 if(/*deviceExtension->*/BaseMemAddress
) {
1051 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
1052 if(ChipFlags
& VIABAR
) {
1054 ULONG BaseIoAddressBM_0
;
1057 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
1058 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
1059 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
1060 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
1061 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
1062 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1064 chan
= &deviceExtension
->chan
[c
];
1066 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, /*0x80*/ sizeof(IDE_REGISTERS_1
) + sizeof(IDE_REGISTERS_2
)*2);
1068 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
1069 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
1071 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2;
1072 UniataInitSyncBaseIO(chan
);
1074 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
1075 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
1080 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1081 chan
= &deviceExtension
->chan
[c
];
1082 if((ChipFlags
& VIABAR
) && (c
==2)) {
1083 // Do not setup SATA registers for PATA part
1084 for (i
=0; i
<=IDX_SATA_IO_SZ
; i
++) {
1085 chan
->RegTranslation
[IDX_SATA_IO
+i
].Addr
= 0;
1086 chan
->RegTranslation
[IDX_SATA_IO
+i
].MemIo
= 0;
1090 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
1091 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1092 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
1093 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1094 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
1095 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1097 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1103 case ATA_INTEL_ID
: {
1105 if(!(ChipFlags
& UNIATA_SATA
)) {
1109 /* the intel 31244 needs special care if in DPA mode */
1110 if(DeviceID
== 3200 && // Intel 31244
1111 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1113 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
1114 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1116 if(!BaseMemAddress
) {
1117 return STATUS_UNSUCCESSFUL
;
1119 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
1120 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1123 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
1124 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1125 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1127 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1128 ULONG offs
= 0x200 + c
*0x200;
1130 chan
= &deviceExtension
->chan
[c
];
1131 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
1132 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
1133 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
1136 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
1137 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
1138 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
1139 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
1140 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
1141 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
1142 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
1143 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
1145 UniataInitSyncBaseIO(chan
);
1147 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
1148 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
1149 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
1151 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
1152 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
1154 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
1155 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
1156 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
1157 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
1158 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
1159 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
1161 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
1162 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1163 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
1164 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1165 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
1166 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1168 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1173 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
1175 BOOLEAN OrigAHCI
= FALSE
;
1177 GetPciConfig1(0x90, tmp8
);
1178 KdPrint2((PRINT_PREFIX
"Intel chip config: %x\n", tmp8
));
1179 /* SATA parts can be either compat or AHCI */
1181 if(ChipFlags
& UNIATA_AHCI
) {
1184 //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
1186 KdPrint2((PRINT_PREFIX
"try run AHCI\n"));
1189 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1190 4, 0, sizeof(IDE_BUSMASTER_REGISTERS
));
1191 if(BaseIoAddressBM
) {
1192 KdPrint2((PRINT_PREFIX
"Intel BM check at %x\n", BaseIoAddressBM
));
1193 /* check if we really have valid BM registers */
1194 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
1195 KdPrint2((PRINT_PREFIX
"MemIo[4]\n"));
1198 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseIoAddressBM
;
1199 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
1201 tmp8
= AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),IDX_BM_Status
);
1202 KdPrint2((PRINT_PREFIX
"BM status: %x\n", tmp8
));
1204 ScsiPortFreeDeviceBase(HwDeviceExtension
, (PCHAR
)BaseIoAddressBM
);
1205 deviceExtension
->BaseIoAddressBM_0
.Addr
= 0;
1206 deviceExtension
->BaseIoAddressBM_0
.MemIo
= 0;
1209 KdPrint2((PRINT_PREFIX
"invalid BM status, keep AHCI mode\n"));
1213 KdPrint2((PRINT_PREFIX
"Compatible mode, reallocate LUNs\n"));
1214 deviceExtension
->NumberLuns
= 2; // we may be in Legacy mode
1215 if(!UniataAllocateLunExt(deviceExtension
, 2)) {
1216 KdPrint2((PRINT_PREFIX
"can't re-allocate Luns\n"));
1217 return STATUS_UNSUCCESSFUL
;
1220 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
1223 /* if BAR(5) is IO it should point to SATA interface registers */
1225 /* Skip BAR(5) in compatible mode */
1226 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on compatible\n"));
1229 if(deviceExtension
->DevID
== 0x28288086 &&
1230 pciData
->u
.type0
.SubVendorID
== 0x106b) {
1231 /* Skip BAR(5) on ICH8M Apples, system locks up on access. */
1232 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on ICH8M Apples\n"));
1235 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1237 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1238 KdPrint2((PRINT_PREFIX
"MemIo[5]\n"));
1242 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1243 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1245 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1246 chan
= &deviceExtension
->chan
[c
];
1248 if(ChipFlags
& ICH5
) {
1249 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1250 if ((tmp8
& 0x04) == 0) {
1251 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1252 } else if ((tmp8
& 0x02) == 0) {
1255 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1257 } else if ((tmp8
& 0x02) != 0) {
1260 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1264 if(ChipFlags
& I6CH2
) {
1265 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1266 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1268 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1269 switch(tmp8
& 0x03) {
1286 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1287 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1290 if(!(ChipFlags
& ICH7
) && BaseMemAddress
) {
1291 KdPrint2((PRINT_PREFIX
"BaseMemAddress[5] -> indexed\n"));
1292 chan
->RegTranslation
[IDX_INDEXED_ADDR
].Addr
= BaseMemAddress
+ 0;
1293 chan
->RegTranslation
[IDX_INDEXED_ADDR
].MemIo
= MemIo
;
1294 chan
->RegTranslation
[IDX_INDEXED_DATA
].Addr
= BaseMemAddress
+ 4;
1295 chan
->RegTranslation
[IDX_INDEXED_DATA
].MemIo
= MemIo
;
1297 if((ChipFlags
& ICH5
) || BaseMemAddress
) {
1299 KdPrint2((PRINT_PREFIX
"io proc()\n"));
1300 // Rather interesting way of register access...
1301 ChipType
= INTEL_IDX
;
1302 deviceExtension
->HwFlags
&= ~CHIPTYPE_MASK
;
1303 deviceExtension
->HwFlags
|= ChipType
;
1305 if(ChipFlags
& ICH7
) {
1306 KdPrint2((PRINT_PREFIX
"ICH7 way\n"));
1308 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= 0x200*c
+ 0; // this is fake non-zero value
1309 chan
->RegTranslation
[IDX_SATA_SStatus
].Proc
= 1;
1310 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= 0x200*c
+ 2; // this is fake non-zero value
1311 chan
->RegTranslation
[IDX_SATA_SError
].Proc
= 1;
1312 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= 0x200*c
+ 1; // this is fake non-zero value
1313 chan
->RegTranslation
[IDX_SATA_SControl
].Proc
= 1;
1319 // rest of INIT staff is in AtapiChipInit()
1324 /* Cyrix 5530 ATA33 controller */
1325 if(deviceExtension
->DevID
== 0x01021078) {
1326 ConfigInfo
->AlignmentMask
= 0x0f;
1327 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
1330 case ATA_JMICRON_ID
:
1331 /* New JMicron PATA controllers */
1332 GetPciConfig1(0xdf, tmp8
);
1334 KdPrint((" Check JMicron AHCI\n"));
1335 if(Ata_is_ahci_dev(pciData
)) {
1336 ChipFlags
|= UNIATA_AHCI
;
1337 deviceExtension
->HwFlags
|= UNIATA_AHCI
;
1339 KdPrint((" JMicron PATA\n"));
1342 /* set controller configuration to a combined setup we support */
1343 SetPciConfig4(0x40, 0x80c0a131);
1344 SetPciConfig4(0x80, 0x01200000);
1345 //KdPrint((" JMicron Combined (not supported yet)\n"));
1346 //return STATUS_NOT_FOUND;
1351 return STATUS_SUCCESS
;
1353 } // end UniataChipDetect()
1357 Do some 'magic staff' for VIA SouthBridge
1358 This will prevent data losses
1362 AtapiViaSouthBridgeFixup(
1363 IN PVOID HwDeviceExtension
,
1364 IN BUS_DATA_TYPE BusDataType
,
1365 IN ULONG SystemIoBusNumber
,
1369 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1370 PCI_COMMON_CONFIG pciData
;
1376 PCI_SLOT_NUMBER slotData
;
1378 BOOLEAN found
= FALSE
;
1380 slotData
.u
.AsULONG
= slotNumber
;
1381 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1383 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1385 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1390 PCI_COMMON_HDR_LENGTH
);
1392 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1396 VendorID
= pciData
.VendorID
;
1397 DeviceID
= pciData
.DeviceID
;
1398 dev_id
= (VendorID
| (DeviceID
<< 16));
1400 if (dev_id
== 0x03051106 || /* VIA VT8363 */
1401 dev_id
== 0x03911106 || /* VIA VT8371 */
1402 dev_id
== 0x31021106 || /* VIA VT8662 */
1403 dev_id
== 0x31121106) { /* VIA VT8361 */
1406 GetPciConfig1(0x76, reg76
);
1408 if ((reg76
& 0xf0) != 0xd0) {
1409 SetPciConfig1(0x75, 0x80);
1410 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
1417 deviceExtension
->HwFlags
&= ~VIABUG
;
1419 } // end AtapiViaSouthBridgeFixup()
1422 Do some 'magic staff' for ROSB SouthBridge
1423 This will prevent data losses
1427 AtapiRosbSouthBridgeFixup(
1428 IN PVOID HwDeviceExtension
,
1429 IN BUS_DATA_TYPE BusDataType
,
1430 IN ULONG SystemIoBusNumber
,
1434 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1435 PCI_COMMON_CONFIG pciData
;
1441 PCI_SLOT_NUMBER slotData
;
1443 // BOOLEAN found = FALSE;
1445 /* locate the ISA part in the southbridge and enable UDMA33 */
1446 slotData
.u
.AsULONG
= slotNumber
;
1447 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1449 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1451 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1456 PCI_COMMON_HDR_LENGTH
);
1458 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1462 VendorID
= pciData
.VendorID
;
1463 DeviceID
= pciData
.DeviceID
;
1464 dev_id
= (VendorID
| (DeviceID
<< 16));
1466 if (dev_id
== ATA_ROSB4_ISA
) { /* */
1467 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1471 } // end AtapiRosbSouthBridgeFixup()
1474 Do some 'magic staff' for ROSB SouthBridge
1475 This will prevent data losses
1479 AtapiAliSouthBridgeFixup(
1480 IN PVOID HwDeviceExtension
,
1481 IN BUS_DATA_TYPE BusDataType
,
1482 IN ULONG SystemIoBusNumber
,
1483 IN ULONG slotNumber
,
1487 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1488 PCI_COMMON_CONFIG pciData
;
1494 PCI_SLOT_NUMBER slotData
;
1496 // BOOLEAN found = FALSE;
1498 /* workaround for datacorruption bug found on at least SUN Blade-100
1499 * find the ISA function on the southbridge and disable then enable
1500 * the ATA channel tristate buffer */
1501 slotData
.u
.AsULONG
= slotNumber
;
1502 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1504 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1506 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1511 PCI_COMMON_HDR_LENGTH
);
1513 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1517 VendorID
= pciData
.VendorID
;
1518 DeviceID
= pciData
.DeviceID
;
1519 dev_id
= (VendorID
| (DeviceID
<< 16));
1521 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1522 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1523 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1527 } // end AtapiRosbSouthBridgeFixup()
1532 IN PHW_DEVICE_EXTENSION deviceExtension
,
1533 IN ULONG channel
// physical channel number (0-1)
1536 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1537 ULONG slotNumber
= deviceExtension
->slotNumber
;
1538 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1540 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1542 UCHAR reg
, val
, res
;
1543 PCI_SLOT_NUMBER slotData
;
1545 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1547 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1548 reg
= channel
? 0x57 : 0x53;
1549 GetPciConfig1(reg
, val
);
1550 SetPciConfig1(reg
, val
| 0x80);
1554 GetPciConfig1(reg
, val
);
1555 SetPciConfig1(reg
, val
& 0xfe);
1557 GetPciConfig1(0x5a, res
);
1558 res
= res
& (channel
? 0x01 : 0x02);
1559 SetPciConfig1(reg
, val
);
1560 KdPrint2((PRINT_PREFIX
"hpt_cable80(%d) = %d\n", channel
, !res
));
1562 } // end hpt_cable80()
1568 IN PHW_DEVICE_EXTENSION deviceExtension,
1569 IN ULONG channel // physical channel number (0-1)
1572 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1573 ULONG slotNumber = deviceExtension->slotNumber;
1574 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1576 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1583 GetPciConfig1(0x50, reg50);
1600 for (j=0; j>=2; i -= 8) {
1601 i = (3-(channel*2+j))*8;
1602 if (((reg50 >> (i & 0x10)) & 8) &&
1603 ((reg50 >> i) & 0x20) &&
1604 (((reg50 >> i) & 7) < a)) {
1606 res |= TRUE; //(1 << (1 - (i >> 4)));
1609 KdPrint2((PRINT_PREFIX "via_cable80(%d) = %d\n", channel, res));
1612 } // end via_cable80()
1618 IN PHW_DEVICE_EXTENSION deviceExtension
,
1619 IN ULONG channel
, // physical channel number (0-1)
1624 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1625 ULONG slotNumber
= deviceExtension
->slotNumber
;
1626 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1628 if(deviceExtension
->MaxTransferMode
<= ATA_UDMA2
) {
1629 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) <= UDMA2\n", channel
, pci_reg
, bit_offs
));
1633 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1635 ULONG c
; // logical channel (for Compatible Mode controllers)
1638 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1639 chan
= &deviceExtension
->chan
[c
];
1641 GetPciConfig1(pci_reg
, tmp8
);
1642 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1643 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1644 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 0\n", channel
, pci_reg
, bit_offs
));
1648 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 1\n", channel
, pci_reg
, bit_offs
));
1650 } // end generic_cable80()
1654 UniAtaReadLunConfig(
1655 IN PHW_DEVICE_EXTENSION deviceExtension
,
1656 IN ULONG channel
, // physical channel
1657 IN ULONG DeviceNumber
1662 PHW_LU_EXTENSION LunExt
;
1665 c
= channel
- deviceExtension
->Channel
; // logical channel
1667 chan
= &deviceExtension
->chan
[c
];
1668 DeviceNumber
= (DeviceNumber
% deviceExtension
->NumberLuns
);
1669 LunExt
= chan
->lun
[DeviceNumber
];
1671 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadCacheEnable", 1);
1672 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1674 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"WriteCacheEnable", 1);
1675 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1677 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1678 LunExt
->opt_MaxTransferMode
= tmp32
;
1680 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"PreferedTransferMode", 0xffffffff);
1681 LunExt
->opt_PreferedTransferMode
= tmp32
;
1683 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"AdvancedPowerMode", ATA_C_F_APM_CNT_MIN_NO_STANDBY
);
1685 tmp32
= 0xfe; // max. performance
1687 LunExt
->opt_AdvPowerMode
= (UCHAR
)tmp32
;
1689 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"AcousticMgmt", ATA_C_F_AAM_CNT_MAX_POWER_SAVE
);
1691 tmp32
= 0xfe; // max. performance
1694 tmp32
= 0x0; // disable feature
1696 LunExt
->opt_AcousticMode
= (UCHAR
)tmp32
;
1698 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"StandbyTimer", 0);
1702 LunExt
->opt_StandbyTimer
= (UCHAR
)tmp32
;
1704 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadOnly", 0);
1706 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1709 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"GeomType", 0xffffffff);
1710 if(tmp32
> GEOM_MANUAL
) {
1713 LunExt
->opt_GeomType
= tmp32
;
1714 if(tmp32
== GEOM_MANUAL
) {
1715 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1716 LunExt
->opt_GeomType
= GEOM_ORIG
;
1717 // assume IdentifyData is already zero-filled
1718 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"C", 0);
1719 LunExt
->IdentifyData
.NumberOfCurrentCylinders
=
1720 LunExt
->IdentifyData
.NumberOfCylinders
= (USHORT
)tmp32
;
1721 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"H", 0);
1722 LunExt
->IdentifyData
.NumberOfCurrentHeads
=
1723 LunExt
->IdentifyData
.NumberOfHeads
= (USHORT
)tmp32
;
1724 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"S", 0);
1725 LunExt
->IdentifyData
.CurrentSectorsPerTrack
=
1726 LunExt
->IdentifyData
.SectorsPerTrack
= (USHORT
)tmp32
;
1727 memcpy(LunExt
->IdentifyData
.ModelNumber
, "SEIDH DD", 8); // ESDI HDD
1728 memcpy(LunExt
->IdentifyData
.SerialNumber
, ".10", 4);
1729 memcpy(LunExt
->IdentifyData
.FirmwareRevision
, ".10", 4);
1730 if(!LunExt
->IdentifyData
.SectorsPerTrack
||
1731 !LunExt
->IdentifyData
.NumberOfCylinders
||
1732 !LunExt
->IdentifyData
.NumberOfHeads
) {
1734 KdPrint2((PRINT_PREFIX
"Wrong CHS\n"));
1735 LunExt
->opt_GeomType
= GEOM_AUTO
;
1737 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1738 LunExt
->opt_GeomType
= GEOM_ORIG
;
1742 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"Hidden", 0);
1744 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1749 } // end UniAtaReadLunConfig()
1753 AtapiReadChipConfig(
1754 IN PVOID HwDeviceExtension
,
1755 IN ULONG DeviceNumber
,
1756 IN ULONG channel
// physical channel
1759 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1762 ULONG c
; // logical channel (for Compatible Mode controllers)
1765 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1766 ASSERT(deviceExtension
);
1768 if(channel
!= CHAN_NOT_SPECIFIED
) {
1769 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1771 c
= CHAN_NOT_SPECIFIED
;
1774 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1776 if(channel
== CHAN_NOT_SPECIFIED
) {
1777 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1778 deviceExtension
->simplexOnly
= TRUE
;
1780 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1781 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1782 deviceExtension
->opt_AtapiDmaRawRead
= g_opt_AtapiDmaRawRead
;
1783 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1786 if(c
== CHAN_NOT_SPECIFIED
) {
1787 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1788 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1789 chan
= &deviceExtension
->chan
[c
];
1790 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1791 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1792 if(tmp32
!= 0xffffffff) {
1793 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1794 chan
->MaxTransferMode
= tmp32
;
1796 //UniAtaReadLunConfig(deviceExtension, c, 0);
1797 //UniAtaReadLunConfig(deviceExtension, c, 1);
1800 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1801 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1804 deviceExtension
->opt_AtapiDmaControlCmd
=
1805 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1808 deviceExtension
->opt_AtapiDmaRawRead
=
1809 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1812 deviceExtension
->opt_AtapiDmaReadWrite
=
1813 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1817 chan
= &deviceExtension
->chan
[c
];
1818 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1819 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1820 if(tmp32
!= 0xffffffff) {
1821 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1822 chan
->MaxTransferMode
= tmp32
;
1824 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1825 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1827 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1828 UniAtaReadLunConfig(deviceExtension
, channel
, i
);
1833 } // end AtapiReadChipConfig()
1838 IN PVOID HwDeviceExtension
,
1839 IN ULONG DeviceNumber
,
1840 IN ULONG channel
// logical channel
1843 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1844 ULONG slotNumber
= deviceExtension
->slotNumber
;
1845 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1846 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1847 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1848 ULONG RevID
= deviceExtension
->RevID
;
1850 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1851 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1852 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1857 ULONG c
; // logical channel (for Compatible Mode controllers)
1858 BOOLEAN CheckCable
= FALSE
;
1859 BOOLEAN GlobalInit
= FALSE
;
1860 //ULONG BaseIoAddress;
1863 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1866 case CHAN_NOT_SPECIFIED
:
1867 c
= CHAN_NOT_SPECIFIED
;
1871 //c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1873 channel
+= deviceExtension
->Channel
;
1876 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d, c %d\n", DeviceNumber
, channel
, c
));
1878 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1879 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1881 if(deviceExtension
->UnknownDev
) {
1882 KdPrint2((PRINT_PREFIX
" Unknown chip\n" ));
1884 VendorID
= 0xffffffff;
1888 if(ChipFlags
& UNIATA_AHCI
) {
1889 /* if BAR(5) is IO it should point to SATA interface registers */
1890 if(!deviceExtension
->BaseIoAHCI_0
.Addr
) {
1891 KdPrint2((PRINT_PREFIX
" !BaseIoAHCI_0, exiting\n" ));
1894 if(c
== CHAN_NOT_SPECIFIED
) {
1895 return UniataAhciInit(HwDeviceExtension
);
1897 if(c
<deviceExtension
->NumberChannels
) {
1898 KdPrint2((PRINT_PREFIX
" AHCI single channel init\n" ));
1899 UniataAhciReset(HwDeviceExtension
, c
);
1902 KdPrint2((PRINT_PREFIX
" AHCI non-existent channel\n" ));
1907 if((WinVer_Id() > WinVer_NT
) &&
1909 deviceExtension
->MasterDev
) {
1910 PCI_COMMON_CONFIG pciData
;
1913 KdPrint2((PRINT_PREFIX
" re-enable IO resources of MasterDev\n" ));
1915 busDataRead
= HalGetBusData
1916 //ScsiPortGetBusData
1918 //HwDeviceExtension,
1919 PCIConfiguration
, SystemIoBusNumber
, slotNumber
,
1920 &pciData
, PCI_COMMON_HDR_LENGTH
);
1921 if(busDataRead
== PCI_COMMON_HDR_LENGTH
) {
1922 UniataEnableIoPCI(SystemIoBusNumber
, slotNumber
, &pciData
);
1924 KdPrint2((PRINT_PREFIX
" re-enable IO resources of MasterDev FAILED\n" ));
1929 // case ATA_ACARD_ID:
1931 case ATA_ACER_LABS_ID
:
1932 if(ChipFlags
& UNIATA_SATA
) {
1933 if(c
== CHAN_NOT_SPECIFIED
) {
1934 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1935 chan
= &deviceExtension
->chan
[c
];
1936 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1937 /* the southbridge might need the data corruption fix */
1938 if(RevID
== 0xc2 || RevID
== 0xc3) {
1939 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1940 SystemIoBusNumber
, slotNumber
, c
);
1943 /* enable PCI interrupt */
1944 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1947 if(ChipFlags
& ALINEW
) {
1948 if(c
== CHAN_NOT_SPECIFIED
) {
1949 /* use device interrupt as byte count end */
1950 ChangePciConfig1(0x4a, (a
| 0x20));
1951 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
1953 ChangePciConfig1(0x4b, (a
| 0x09));
1956 /* enable ATAPI UDMA mode */
1957 ChangePciConfig1(0x53, (a
| (RevID
>= 0xc7 ? 0x03 : 0x01)));
1960 // check 80-pin cable
1961 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
1964 if(c
== CHAN_NOT_SPECIFIED
) {
1965 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1966 ChangePciConfig1(0x53, (a
| 0x03));
1969 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1974 if(c
== CHAN_NOT_SPECIFIED
) {
1975 /* set prefetch, postwrite */
1976 if(ChipFlags
& AMDBUG
) {
1977 ChangePciConfig1(0x41, (a
& 0x0f));
1979 ChangePciConfig1(0x41, (a
| 0xf0));
1982 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1984 // check 80-pin cable
1985 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
1986 if(c
== CHAN_NOT_SPECIFIED
) {
1989 generic_cable80(deviceExtension
, channel
, 0x42, 0);
1993 case ATA_HIGHPOINT_ID
:
1995 if(c
== CHAN_NOT_SPECIFIED
) {
1997 if(ChipFlags
& HPTOLD
) {
1998 /* turn off interrupt prediction */
1999 ChangePciConfig1(0x51, (a
& ~0x80));
2001 /* turn off interrupt prediction */
2002 ChangePciConfig1(0x51, (a
& ~0x03));
2003 ChangePciConfig1(0x55, (a
& ~0x03));
2004 /* turn on interrupts */
2005 ChangePciConfig1(0x5a, (a
& ~0x10));
2006 /* set clocks etc */
2007 if(ChipType
< HPT372
) {
2008 SetPciConfig1(0x5b, 0x22);
2010 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
2015 // check 80-pin cable
2016 chan
= &deviceExtension
->chan
[c
];
2017 if(!hpt_cable80(deviceExtension
, channel
)) {
2018 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2022 case ATA_INTEL_ID
: {
2026 if(ChipFlags
& UNIATA_SATA
) {
2028 KdPrint2((PRINT_PREFIX
"Intel SATA\n"));
2029 if(ChipFlags
& UNIATA_AHCI
) {
2030 KdPrint2((PRINT_PREFIX
"Do nothing for AHCI\n"));
2033 if(c
== CHAN_NOT_SPECIFIED
) {
2034 KdPrint2((PRINT_PREFIX
"Base init\n"));
2035 /* force all ports active "the legacy way" */
2036 ChangePciConfig2(0x92, (a
| 0x0f));
2038 if(deviceExtension
->BaseIoAddressSATA_0
.Addr
&& (ChipFlags
& ICH7
)) {
2039 /* Set SCRAE bit to enable registers access. */
2040 ChangePciConfig4(0x94, (a
| (1 << 9)));
2041 /* Set Ports Implemented register bits. */
2042 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x0c,
2043 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x0c) | 0x0f);
2045 /* enable PCI interrupt */
2046 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2050 KdPrint2((PRINT_PREFIX
"channel init\n"));
2052 GetPciConfig1(0x90, tmp8
);
2053 KdPrint2((PRINT_PREFIX
"reg 90: %x, init lun map\n", tmp8
));
2055 KdPrint2((PRINT_PREFIX
"chan %d\n", c
));
2056 chan
= &deviceExtension
->chan
[c
];
2058 if(ChipFlags
& ICH5
) {
2059 KdPrint2((PRINT_PREFIX
"ICH5\n"));
2060 if ((tmp8
& 0x04) == 0) {
2061 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2062 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ^ c
;
2063 chan
->lun
[1]->SATA_lun_map
= 0;
2064 } else if ((tmp8
& 0x02) == 0) {
2066 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
2067 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
2070 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2072 } else if ((tmp8
& 0x02) != 0) {
2074 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
2075 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
2078 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2082 if(ChipFlags
& I6CH2
) {
2083 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
2084 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2085 chan
->lun
[0]->SATA_lun_map
= c
? 0 : 1;
2086 chan
->lun
[1]->SATA_lun_map
= 0;
2088 KdPrint2((PRINT_PREFIX
"other Intel\n"));
2089 switch(tmp8
& 0x03) {
2091 KdPrint2((PRINT_PREFIX
"0 -> %d/%d\n", 0+c
, 2+c
));
2092 chan
->lun
[0]->SATA_lun_map
= 0+c
;
2093 chan
->lun
[1]->SATA_lun_map
= 2+c
;
2097 KdPrint2((PRINT_PREFIX
"2 -> %d/%d\n", 0, 2));
2098 chan
->lun
[0]->SATA_lun_map
= 0;
2099 chan
->lun
[1]->SATA_lun_map
= 2;
2102 KdPrint2((PRINT_PREFIX
"PATA\n"));
2108 KdPrint2((PRINT_PREFIX
"2 -> %d/%d\n", 1, 3));
2109 chan
->lun
[0]->SATA_lun_map
= 1;
2110 chan
->lun
[1]->SATA_lun_map
= 3;
2113 KdPrint2((PRINT_PREFIX
"PATA\n"));
2121 KdPrint2((PRINT_PREFIX
"PATA part\n"));
2122 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2125 if(ChipType
== INTEL_IDX
) {
2126 KdPrint2((PRINT_PREFIX
"io indexed\n"));
2127 //for(c=0; c<deviceExtension->NumberChannels; c++) {
2128 chan
= &deviceExtension
->chan
[c
];
2129 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2130 if(!(chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
)) {
2131 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 1);
2139 if(deviceExtension
->MaxTransferMode
<= ATA_UDMA2
)
2141 // check 80-pin cable
2142 if(c
== CHAN_NOT_SPECIFIED
) {
2145 chan
= &deviceExtension
->chan
[c
];
2146 GetPciConfig2(0x54, reg54
);
2147 KdPrint2((PRINT_PREFIX
" intel 80-pin check (reg54=%x)\n", reg54
));
2148 if(reg54
== 0x0000 || reg54
== 0xffff) {
2149 KdPrint2((PRINT_PREFIX
" check failed (not supported)\n"));
2151 if( ((reg54
>> (channel
*2)) & 30) == 0) {
2152 KdPrint2((PRINT_PREFIX
" intel 40-pin\n"));
2153 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2157 case ATA_NVIDIA_ID
: {
2158 if(ChipFlags
& UNIATA_SATA
) {
2159 if(c
== CHAN_NOT_SPECIFIED
) {
2160 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
2161 /* enable control access */
2162 ChangePciConfig1(0x50, (a
| 0x04));
2163 /* MCP55 seems to need some time to allow r_res2 read. */
2164 AtapiStallExecution(10);
2165 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
2166 if(ChipFlags
& NVQ
) {
2167 /* clear interrupt status */
2168 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
2169 /* enable device and PHY state change interrupts */
2170 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
2171 /* disable NCQ support */
2172 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
2173 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
2175 /* clear interrupt status */
2176 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
2177 /* enable device and PHY state change interrupts */
2178 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
2180 /* enable PCI interrupt */
2181 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2183 //UniataSataPhyEnable(HwDeviceExtension, c);
2188 if(c
== CHAN_NOT_SPECIFIED
) {
2189 /* set prefetch, postwrite */
2190 ChangePciConfig1(0x51, (a
& 0x0f));
2192 // check 80-pin cable
2193 generic_cable80(deviceExtension
, channel
, 0x52, 1);
2194 /* chan = &deviceExtension->chan[c];
2195 GetPciConfig1(0x52, reg52);
2196 if( !((reg52 >> (channel*2)) & 0x01)) {
2197 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2202 case ATA_PROMISE_ID
: {
2207 if(c
== CHAN_NOT_SPECIFIED
) {
2208 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
2209 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
2210 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
2214 /* enable burst mode */
2215 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
2216 if(c
== CHAN_NOT_SPECIFIED
) {
2217 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
2218 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
2220 // check 80-pin cable
2221 chan
= &deviceExtension
->chan
[c
];
2222 GetPciConfig2(0x50, Reg50
);
2223 if(Reg50
& (1 << (channel
+10))) {
2224 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2229 if(c
== CHAN_NOT_SPECIFIED
) {
2232 // check 80-pin cable
2233 chan
= &deviceExtension
->chan
[c
];
2234 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
2235 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
2236 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2241 if(c
== CHAN_NOT_SPECIFIED
) {
2242 /* clear SATA status and unmask interrupts */
2243 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),
2244 (ChipFlags
& PRG2
) ? 0x60 : 0x6c, 0x000000ff);
2245 if(ChipFlags
& UNIATA_SATA
) {
2246 /* enable "long burst length" on gen2 chips */
2247 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
), 0x44,
2248 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
), 0x44) | 0x2000);
2251 chan
= &deviceExtension
->chan
[c
];
2252 AtapiWritePort4(chan
, IDX_BM_Command
,
2253 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
2254 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
2255 // check 80-pin cable
2256 if(chan
->MaxTransferMode
< ATA_SA150
&&
2257 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
2258 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2264 case ATA_SERVERWORKS_ID
:
2265 if(c
== CHAN_NOT_SPECIFIED
) {
2266 if(ChipType
== SWKS33
) {
2267 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2268 SystemIoBusNumber
, slotNumber
);
2270 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
2275 if(ChipType
== SIIMIO
) {
2276 KdPrint2((PRINT_PREFIX
"ATI New\n"));
2279 KdPrint2((PRINT_PREFIX
"ATI\n"));
2283 case ATA_SILICON_IMAGE_ID
:
2284 /* if(ChipFlags & SIIENINTR) {
2285 SetPciConfig1(0x71, 0x01);
2290 KdPrint2((PRINT_PREFIX
"SII\n"));
2293 if(c
== CHAN_NOT_SPECIFIED
) {
2294 if(ChipFlags
& SIISETCLK
) {
2295 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
2296 GetPciConfig1(0x8a, tmp8
);
2297 if ((tmp8
& 0x30) != 0x10)
2298 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
2299 GetPciConfig1(0x8a, tmp8
);
2300 if ((tmp8
& 0x30) != 0x10) {
2301 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
2302 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2306 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
2307 // check 80-pin cable
2308 if(c
== CHAN_NOT_SPECIFIED
) {
2311 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
2312 chan
= &deviceExtension
->chan
[c
];
2313 GetPciConfig2(0x79, Reg79
);
2314 if(Reg79
& (channel
? 0x02 : 0x01)) {
2315 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2319 ULONG unit01
= (c
& 1);
2320 ULONG unit10
= (c
& 2);
2321 /* enable/disable PHY state change interrupt */
2322 if(c
== CHAN_NOT_SPECIFIED
) {
2323 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2326 if(ChipFlags
& SIINOSATAIRQ
) {
2327 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2328 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2332 if(ChipFlags
& SIINOSATAIRQ
) {
2333 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2334 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2336 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
2337 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
2341 if(c
== CHAN_NOT_SPECIFIED
) {
2342 /* enable interrupt as BIOS might not */
2343 ChangePciConfig1(0x8a, (a
& 0x3f));
2344 // Enable 3rd and 4th channels
2345 if (ChipFlags
& SII4CH
) {
2346 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
2347 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
2350 chan
= &deviceExtension
->chan
[c
];
2351 /* dont block interrupts */
2352 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2353 /*tmp32 =*/ AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2354 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
2356 /*tmp32 =*/ AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2358 /* Initialize FIFO PCI bus arbitration */
2359 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
2361 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp8
));
2363 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
2365 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
2372 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
2373 if(c
== CHAN_NOT_SPECIFIED
) {
2374 /* Setup interrupts. */
2375 SetPciConfig1(0x71, 0x01);
2377 /* GetPciConfig1(0x8a, tmp8);
2379 SetPciConfig1(0x71, tmp8);*/
2381 /* Use MEMORY READ LINE for reads.
2382 * NOTE: Although not mentioned in the PCI0646U specs,
2383 * these bits are write only and won't be read
2384 * back as set or not. The PCI0646U2 specs clarify
2388 SetPciConfig1(0x71, tmp8);
2390 /* Set reasonable active/recovery/address-setup values. */
2391 SetPciConfig1(0x53, 0x40);
2392 SetPciConfig1(0x54, 0x3f);
2393 SetPciConfig1(0x55, 0x40);
2394 SetPciConfig1(0x56, 0x3f);
2395 SetPciConfig1(0x57, 0x1c);
2396 SetPciConfig1(0x58, 0x3f);
2397 SetPciConfig1(0x5b, 0x3f);
2402 KdPrint2((PRINT_PREFIX
"ATI700\n"));
2403 if(c
== 0 && !(ChipFlags
& UNIATA_AHCI
)) {
2404 KdPrint2((PRINT_PREFIX
"IXP700 PATA\n"));
2405 chan
= &deviceExtension
->chan
[c
];
2406 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2409 } /* switch(ChipType) */
2412 if(c
== CHAN_NOT_SPECIFIED
) {
2418 ChangePciConfig1(0x52, (a
& ~0x04));
2422 ChangePciConfig1(0x49, (a
& ~0x01));
2425 ChangePciConfig2(0x50, (a
| 0x0008));
2426 ChangePciConfig2(0x52, (a
| 0x0008));
2429 ChangePciConfig2(0x04, (a
& ~0x0400));
2433 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
2434 // do nothing for SATA
2436 if(ChipType
== SIS133NEW
) {
2438 // check 80-pin cable
2439 if(c
== CHAN_NOT_SPECIFIED
) {
2442 chan
= &deviceExtension
->chan
[c
];
2443 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
2444 if(tmp16
& 0x8000) {
2445 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2449 // check 80-pin cable
2450 if(c
== CHAN_NOT_SPECIFIED
) {
2453 chan
= &deviceExtension
->chan
[c
];
2454 GetPciConfig1(48, tmp8
);
2455 if(tmp8
& (0x10 << channel
)) {
2456 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2463 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2466 if(c
== CHAN_NOT_SPECIFIED
) {
2467 /* prepare for ATA-66 on the 82C686a and 82C596b */
2468 if(ChipFlags
& VIACLK
) {
2469 ChangePciConfig4(0x50, (a
| 0x030b030b));
2472 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2473 /* enable PCI interrupt */
2474 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2477 * vt6420/1 has problems talking to some drives. The following
2478 * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
2480 * When host issues HOLD, device may send up to 20DW of data
2481 * before acknowledging it with HOLDA and the host should be
2482 * able to buffer them in FIFO. Unfortunately, some WD drives
2483 * send upto 40DW before acknowledging HOLD and, in the
2484 * default configuration, this ends up overflowing vt6421's
2485 * FIFO, making the controller abort the transaction with
2488 * Rx52[2] is the internal 128DW FIFO Flow control watermark
2489 * adjusting mechanism enable bit and the default value 0
2490 * means host will issue HOLD to device when the left FIFO
2491 * size goes below 32DW. Setting it to 1 makes the watermark
2494 * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
2497 if(DeviceID
== 0x3149 || DeviceID
== 0x3249) { //vt6420 or vt6421
2498 KdPrint2((PRINT_PREFIX
"VIA 642x FIFO\n"));
2499 ChangePciConfig1(0x52, a
| (1 << 2));
2505 /* the southbridge might need the data corruption fix */
2506 if(ChipFlags
& VIABUG
) {
2507 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2508 SystemIoBusNumber
, slotNumber
);
2510 /* set prefetch, postwrite */
2511 if(ChipType
!= VIA133
) {
2512 ChangePciConfig1(0x41, (a
| 0xf0));
2515 /* set fifo configuration half'n'half */
2516 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
2518 /* set status register read retry */
2519 ChangePciConfig1(0x44, (a
| 0x08));
2521 /* set DMA read & end-of-sector fifo flush */
2522 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
2524 /* set sector size */
2525 SetPciConfig2(0x60, DEV_BSIZE
);
2526 SetPciConfig2(0x68, DEV_BSIZE
);
2529 chan
= &deviceExtension
->chan
[c
];
2531 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2532 if((ChipFlags
& VIABAR
) && (c
>= 2)) {
2533 // this is PATA channel
2534 chan
->MaxTransferMode
= ATA_UDMA5
;
2537 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2541 // check 80-pin cable
2542 if(!via_cable80(deviceExtension, channel)) {
2543 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2551 if(ChipType
== ITE_33
|| ChipType
== ITE_133_NEW
) {
2554 if(ChipType
== ITE_133
) {
2555 if(c
== CHAN_NOT_SPECIFIED
) {
2556 /* set PCI mode and 66Mhz reference clock */
2557 ChangePciConfig1(0x50, a
& ~0x83);
2559 /* set default active & recover timings */
2560 SetPciConfig1(0x54, 0x31);
2561 SetPciConfig1(0x56, 0x31);
2563 // check 80-pin cable
2564 GetPciConfig2(0x40, tmp16
);
2565 chan
= &deviceExtension
->chan
[c
];
2566 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
2567 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2571 if(ChipType
== ITE_133_NEW
) {
2575 if(c
!= CHAN_NOT_SPECIFIED
) {
2576 // We don't know how to check for 80-pin cable on unknown controllers.
2577 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2578 // So, leave this flag to use as hint in error recovery procedures
2579 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
2580 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
2585 // In all places separate channels are inited after common controller init
2586 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2587 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
2588 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2589 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
2594 } // end AtapiChipInit()
2599 IN PHW_DEVICE_EXTENSION deviceExtension
,
2600 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
2608 if(!BaseIoAddressBM_0
) {
2611 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2612 chan
= &deviceExtension
->chan
[c
];
2613 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
2614 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONGIO_PTR
)BaseIoAddressBM_0
+ i
) : 0;
2615 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
2617 if(BaseIoAddressBM_0
) {
2618 BaseIoAddressBM_0
++;
2622 } // end UniataInitMapBM()
2627 IN PHW_CHANNEL chan
,
2628 IN PIDE_REGISTERS_1 BaseIoAddress1
,
2629 IN PIDE_REGISTERS_2 BaseIoAddress2
2634 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
2635 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONGIO_PTR
)BaseIoAddress1
+ i
) : 0;
2636 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
2638 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
2639 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONGIO_PTR
)BaseIoAddress2
+ i
) : 0;
2640 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
2642 UniataInitSyncBaseIO(chan
);
2644 } // end UniataInitMapBase()
2648 UniataInitSyncBaseIO(
2652 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
2653 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
2655 } // end UniataInitSyncBaseIO()
2660 IN PHW_CHANNEL chan
,
2661 IN PHW_DEVICE_EXTENSION deviceExtension
,
2667 KdPrint2((PRINT_PREFIX
"AtapiSetupLunPtrs for channel %d of %d, %d luns \n", c
, deviceExtension
->NumberChannels
, deviceExtension
->NumberLuns
));
2669 if(!deviceExtension
->NumberLuns
) {
2670 KdPrint2((PRINT_PREFIX
"Achtung !deviceExtension->NumberLuns \n"));
2671 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
;
2673 KdPrint2((PRINT_PREFIX
" Chan %#x\n", chan
));
2674 chan
->DeviceExtension
= deviceExtension
;
2676 chan
->NumberLuns
= deviceExtension
->NumberLuns
;
2677 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2678 chan
->lun
[i
] = &(deviceExtension
->lun
[c
*deviceExtension
->NumberLuns
+i
]);
2679 KdPrint2((PRINT_PREFIX
" Lun %#x\n", i
));
2680 KdPrint2((PRINT_PREFIX
" Lun ptr %#x\n", chan
->lun
[i
]));
2682 chan
->AltRegMap
= deviceExtension
->AltRegMap
;
2683 chan
->NextDpcChan
= -1;
2684 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2685 chan
->lun
[i
]->DeviceExtension
= deviceExtension
;
2686 chan
->lun
[i
]->chan
= chan
;
2687 chan
->lun
[i
]->Lun
= i
;
2689 if((deviceExtension
->HwFlags
& UNIATA_AHCI
) &&
2690 deviceExtension
->AhciInternalAtaReq0
&&
2691 deviceExtension
->AhciInternalSrb0
) {
2692 chan
->AhciInternalAtaReq
= &(deviceExtension
->AhciInternalAtaReq0
[c
]);
2693 chan
->AhciInternalSrb
= &(deviceExtension
->AhciInternalSrb0
[c
]);
2694 UniataAhciSetupCmdPtr(chan
->AhciInternalAtaReq
);
2695 chan
->AhciInternalSrb
->SrbExtension
= chan
->AhciInternalAtaReq
;
2696 chan
->AhciInternalAtaReq
->Srb
= chan
->AhciInternalSrb
;
2699 } // end AtapiSetupLunPtrs()
2703 UniataAllocateLunExt(
2704 PHW_DEVICE_EXTENSION deviceExtension
,
2705 ULONG NewNumberChannels
2708 PHW_LU_EXTENSION old_luns
= NULL
;
2709 PHW_CHANNEL old_chans
= NULL
;
2711 KdPrint2((PRINT_PREFIX
"allocate %d Luns for %d channels\n", deviceExtension
->NumberLuns
, deviceExtension
->NumberChannels
));
2713 old_luns
= deviceExtension
->lun
;
2714 old_chans
= deviceExtension
->chan
;
2716 if(old_luns
|| old_chans
) {
2717 if(NewNumberChannels
== UNIATA_ALLOCATE_NEW_LUNS
) {
2718 KdPrint2((PRINT_PREFIX
"already allocated!\n"));
2723 if(!deviceExtension
->NumberLuns
) {
2724 KdPrint2((PRINT_PREFIX
"default NumberLuns=2\n"));
2725 deviceExtension
->NumberLuns
= 2;
2728 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2729 if(!deviceExtension
->AhciInternalAtaReq0
) {
2730 deviceExtension
->AhciInternalAtaReq0
= (PATA_REQ
)ExAllocatePool(NonPagedPool
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2731 if (!deviceExtension
->AhciInternalAtaReq0
) {
2732 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalAtaReq0 => SP_RETURN_ERROR\n"));
2735 RtlZeroMemory(deviceExtension
->AhciInternalAtaReq0
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2737 if(!deviceExtension
->AhciInternalSrb0
) {
2738 deviceExtension
->AhciInternalSrb0
= (PSCSI_REQUEST_BLOCK
)ExAllocatePool(NonPagedPool
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2739 if (!deviceExtension
->AhciInternalSrb0
) {
2740 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalSrb0 => SP_RETURN_ERROR\n"));
2741 UniataFreeLunExt(deviceExtension
);
2744 RtlZeroMemory(deviceExtension
->AhciInternalSrb0
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2748 deviceExtension
->lun
= (PHW_LU_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2749 if (!deviceExtension
->lun
) {
2750 KdPrint2((PRINT_PREFIX
"!deviceExtension->lun => SP_RETURN_ERROR\n"));
2751 UniataFreeLunExt(deviceExtension
);
2754 RtlZeroMemory(deviceExtension
->lun
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2756 deviceExtension
->chan
= (PHW_CHANNEL
)ExAllocatePool(NonPagedPool
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2757 if (!deviceExtension
->chan
) {
2758 UniataFreeLunExt(deviceExtension
);
2759 KdPrint2((PRINT_PREFIX
"!deviceExtension->chan => SP_RETURN_ERROR\n"));
2762 RtlZeroMemory(deviceExtension
->chan
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2764 } // end UniataAllocateLunExt()
2769 PHW_DEVICE_EXTENSION deviceExtension
2772 if (deviceExtension
->lun
) {
2773 ExFreePool(deviceExtension
->lun
);
2774 deviceExtension
->lun
= NULL
;
2776 if (deviceExtension
->chan
) {
2777 ExFreePool(deviceExtension
->chan
);
2778 deviceExtension
->chan
= NULL
;
2780 if(deviceExtension
->AhciInternalAtaReq0
) {
2781 ExFreePool(deviceExtension
->AhciInternalAtaReq0
);
2782 deviceExtension
->AhciInternalAtaReq0
= NULL
;
2784 if(deviceExtension
->AhciInternalSrb0
) {
2785 ExFreePool(deviceExtension
->AhciInternalSrb0
);
2786 deviceExtension
->AhciInternalSrb0
= NULL
;
2790 } // end UniataFreeLunExt()