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_UDMA6
, "SiS 1183" , 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" , 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, 0x00, 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
= 0;
526 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
527 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
530 case 0x81721283: /* IT8172 IDE controller */
531 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
536 return STATUS_NOT_FOUND
;
538 return STATUS_SUCCESS
;
542 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
544 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
545 if(i
== BMLIST_TERMINATOR
) {
547 //return STATUS_NOT_FOUND;
549 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
550 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
552 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
554 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
555 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
556 deviceExtension
->HwFlags
= tmp32
;
558 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
559 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
560 deviceExtension
->HwFlags
|= tmp32
;
562 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
563 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
564 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
568 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
569 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
570 if(tmp32
!= 0xffffffff) {
571 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
572 deviceExtension
->MaxTransferMode
= tmp32
;
575 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
576 deviceExtension
->HwFlags
|= UNIATA_SATA
;
580 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
581 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
583 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
584 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
586 /* for even more ugly AHCI-capable chips */
587 if(ChipFlags
& UNIATA_AHCI
) {
589 Seems, some chips may have inoperable/alternative BAR5 in SATA mode
590 This can be detected via PCI SubClass
595 KdPrint2((PRINT_PREFIX
"ATA_xxx_ID check AHCI subclass\n"));
596 if((pciData
)->SubClass
== PCI_DEV_SUBCLASS_IDE
) {
597 KdPrint2((PRINT_PREFIX
"Non-AHCI mode\n"));
598 ChipFlags
&= ~UNIATA_AHCI
;
599 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
605 if(ChipFlags
& UNIATA_AHCI
) {
606 deviceExtension
->NumberChannels
= 0;
607 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
608 KdPrint2((PRINT_PREFIX
" AHCI detect failed\n"));
609 return STATUS_UNSUCCESSFUL
;
612 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
613 return STATUS_UNSUCCESSFUL
;
615 // UniataAhciDetect() sets proper number of channels
616 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
617 return STATUS_UNSUCCESSFUL
;
621 case ATA_ACER_LABS_ID
:
622 if(ChipFlags
& UNIATA_SATA
) {
623 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
624 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
626 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
628 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
629 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
630 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
631 //ULONG unit01 = (c & 1);
632 ULONG unit10
= (c
& 2);
633 chan
= &deviceExtension
->chan
[c
];
635 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
636 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
638 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
639 UniataInitSyncBaseIO(chan
);
641 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
642 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
645 // SATA not supported yet
647 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
648 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
649 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
651 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
656 if(ChipFlags
& UNIATA_SATA
) {
657 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
658 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
659 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
660 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
661 if(!BaseMemAddress
) {
662 return STATUS_UNSUCCESSFUL
;
664 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
665 KdPrint2((PRINT_PREFIX
"MemIo\n"));
668 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
669 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
670 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
671 chan
= &deviceExtension
->chan
[c
];
673 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
674 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
675 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
676 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
677 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
678 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
680 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
686 if(ChipType
!= PRMIO
) {
692 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
695 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
697 KdPrint2((PRINT_PREFIX
"BaseMemAddress[4] %x\n", BaseMemAddress
));
698 if(!BaseMemAddress
) {
699 return STATUS_UNSUCCESSFUL
;
701 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
702 KdPrint2((PRINT_PREFIX
"MemIo\n"));
705 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
706 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
709 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
711 KdPrint2((PRINT_PREFIX
"BaseMemAddress[3] %x\n", BaseMemAddress
));
712 if(!BaseMemAddress
) {
713 return STATUS_UNSUCCESSFUL
;
715 if((*ConfigInfo
->AccessRanges
)[3].RangeInMemory
) {
716 KdPrint2((PRINT_PREFIX
"MemIo\n"));
719 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
720 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
722 if(!(ChipFlags
& UNIATA_SATA
)) {
725 reg48
= AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
726 deviceExtension
->NumberChannels
= ((reg48
& 0x01) ? 1 : 0) +
727 ((reg48
& 0x02) ? 1 : 0) +
729 KdPrint2((PRINT_PREFIX
"Channels -> %d\n", deviceExtension
->NumberChannels
));
732 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
737 chan
= &deviceExtension
->chan
[c
];
742 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
743 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs7
;
744 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
746 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
747 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
749 UniataInitSyncBaseIO(chan
);
751 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
752 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
753 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
754 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
755 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
756 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
758 if((ChipFlags
& PRSATA
) ||
759 ((ChipFlags
& PRCMBO
) && c
<2)) {
760 KdPrint2((PRINT_PREFIX
"Promise SATA\n"));
762 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x400 + offs7
;
763 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
764 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x404 + offs7
;
765 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
766 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x408 + offs7
;
767 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
769 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
771 KdPrint2((PRINT_PREFIX
"Promise PATA\n"));
772 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA6
);
778 KdPrint2((PRINT_PREFIX
"ATI\n"));
779 if(ChipType
== ATI700
) {
780 KdPrint2((PRINT_PREFIX
"ATI700\n"));
781 if(!(ChipFlags
& UNIATA_AHCI
)) {
782 KdPrint2((PRINT_PREFIX
"IXP700 PATA\n"));
783 chan
= &deviceExtension
->chan
[0];
784 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
789 case ATA_SILICON_IMAGE_ID
: {
791 if(ChipFlags
& SIIBUG
) {
793 if(ChipType
!= SIIMIO
) {
800 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
801 KdPrint2((PRINT_PREFIX
"New SII\n"));
803 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
805 //if(deviceExtension->HwFlags & SII4CH) {
806 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
808 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
810 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
811 if(!BaseMemAddress
) {
812 return STATUS_UNSUCCESSFUL
;
814 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
815 KdPrint2((PRINT_PREFIX
"MemIo\n"));
818 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
819 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
821 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
822 ULONG unit01
= (c
& 1);
823 ULONG unit10
= (c
& 2);
825 chan
= &deviceExtension
->chan
[c
];
827 if(deviceExtension
->AltRegMap
) {
828 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
829 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
830 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
832 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
833 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
834 UniataInitSyncBaseIO(chan
);
836 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
837 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
838 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
839 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
840 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
841 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
842 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
843 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
844 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
845 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
846 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
847 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
850 if(chan
->MaxTransferMode
< ATA_SA150
) {
851 // do nothing for PATA part
852 KdPrint2((PRINT_PREFIX
"No SATA regs for PATA part\n"));
854 if(ChipFlags
& UNIATA_SATA
) {
855 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
856 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
857 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
858 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
859 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
860 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
862 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
867 case ATA_SERVERWORKS_ID
: {
869 if(ChipType
!= SWKSMIO
) {
876 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
878 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
879 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
881 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
882 if(!BaseMemAddress
) {
883 return STATUS_UNSUCCESSFUL
;
885 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
886 KdPrint2((PRINT_PREFIX
"MemIo\n"));
889 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
890 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
892 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
893 ULONG offs
= c
*0x100;
895 chan
= &deviceExtension
->chan
[c
];
896 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
897 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
898 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
900 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
901 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
902 UniataInitSyncBaseIO(chan
);
904 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
905 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
906 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
907 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
908 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
909 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
911 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
912 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
913 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
914 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
915 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
916 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
918 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
923 //if(ChipType != SIS_SOUTH) {}
924 BOOLEAN SIS_182
=FALSE
;
926 if(!(ChipFlags
& SIS_BASE
)) {
927 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
928 //PrintNtConsole("Found SIS_SOUTH\n");
931 // Make some additional checks
932 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
933 ChangePciConfig1(0x57, (a
& 0x7f));
934 GetPciConfig4(0x00, tmp32
);
935 if(tmp32
== ATA_SIS5518
) {
936 ChipType
= SIS133NEW
;
937 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
938 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
939 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
940 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
942 ChangePciConfig1(0x57, (a
| 0x80));
944 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
945 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, ATA_MODE_NOT_SPEC
, "SiS 961", 0 ),
946 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_MODE_NOT_SPEC, "SiS 961", 0 ),
947 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, ATA_MODE_NOT_SPEC
, NULL
, -1 )
950 GetPciConfig1(0x4a, tmp8
);
951 ChangePciConfig1(0x4a, (a
| 0x10));
952 if(tmp32
== ATA_SIS5513
||
953 tmp32
== ATA_SIS5517
) {
954 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
955 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
956 if(i
!= BMLIST_TERMINATOR
) {
957 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
958 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
959 //deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
960 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
961 deviceExtension
->HwFlags
|= UNIATA_SATA
;
962 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182 ||
963 SiSSouthAdapters
[i
].nDeviceId
== 0x1183) {
968 // SiS-South not found
969 if(tmp32
== ATA_SIS5517
) {
970 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
971 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
974 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
979 SetPciConfig1(0x4a, tmp8
);
980 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
981 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
982 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
983 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
985 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
987 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
989 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
990 KdPrint2((PRINT_PREFIX
"MemIo\n"));
993 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
994 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
996 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
997 ULONG offs
= c
<< (SIS_182
? 5 : 6);
999 chan
= &deviceExtension
->chan
[c
];
1000 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
1001 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1002 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
1003 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1004 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
1005 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1007 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1012 //ChangePciConfig1(0x57, (a | 0x80));
1017 if(ChipFlags
& VIASATA
) {
1018 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
1019 // do nothing, generic PATA INIT
1020 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs\n"));
1023 if(ChipFlags
& UNIATA_SATA
) {
1026 ULONG BaseMemAddress
= 0;
1029 case 0x3149: // VIA 6420
1030 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
1033 case 0x3249: // VIA 6421
1034 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
1039 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
1040 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1041 5, 0, IoSize
* deviceExtension
->NumberChannels
);
1042 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1043 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1046 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1047 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1049 if(/*deviceExtension->*/BaseMemAddress
) {
1050 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
1051 if(ChipFlags
& VIABAR
) {
1053 ULONG BaseIoAddressBM_0
;
1056 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
1057 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
1058 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
1059 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
1060 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
1061 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1063 chan
= &deviceExtension
->chan
[c
];
1065 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, /*0x80*/ sizeof(IDE_REGISTERS_1
) + sizeof(IDE_REGISTERS_2
)*2);
1067 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
1068 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
1070 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2;
1071 UniataInitSyncBaseIO(chan
);
1073 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
1074 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
1079 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1080 chan
= &deviceExtension
->chan
[c
];
1081 if((ChipFlags
& VIABAR
) && (c
==2)) {
1082 // Do not setup SATA registers for PATA part
1083 for (i
=0; i
<=IDX_SATA_IO_SZ
; i
++) {
1084 chan
->RegTranslation
[IDX_SATA_IO
+i
].Addr
= 0;
1085 chan
->RegTranslation
[IDX_SATA_IO
+i
].MemIo
= 0;
1089 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
1090 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1091 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
1092 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1093 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
1094 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1096 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1102 case ATA_INTEL_ID
: {
1104 if(!(ChipFlags
& UNIATA_SATA
)) {
1108 /* the intel 31244 needs special care if in DPA mode */
1109 if(DeviceID
== 3200 && // Intel 31244
1110 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
1112 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
1113 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1115 if(!BaseMemAddress
) {
1116 return STATUS_UNSUCCESSFUL
;
1118 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
1119 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1122 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
1123 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1124 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1126 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1127 ULONG offs
= 0x200 + c
*0x200;
1129 chan
= &deviceExtension
->chan
[c
];
1130 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
1131 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
1132 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
1135 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
1136 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
1137 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
1138 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
1139 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
1140 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
1141 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
1142 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
1144 UniataInitSyncBaseIO(chan
);
1146 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
1147 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
1148 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
1150 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
1151 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
1153 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
1154 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
1155 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
1156 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
1157 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
1158 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
1160 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
1161 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
1162 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
1163 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1164 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
1165 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1167 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1172 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
1173 GetPciConfig1(0x90, tmp8
);
1174 KdPrint2((PRINT_PREFIX
"Intel chip config: %x\n", tmp8
));
1175 /* SATA parts can be either compat or AHCI */
1176 if(ChipFlags
& UNIATA_AHCI
) {
1179 //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
1181 KdPrint2((PRINT_PREFIX
"try run AHCI\n"));
1184 KdPrint2((PRINT_PREFIX
"Compatible mode\n"));
1186 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
1188 /* if BAR(5) is IO it should point to SATA interface registers */
1189 if(deviceExtension
->DevID
== 0x28288086 &&
1190 pciData
->u
.type0
.SubVendorID
== 0x106b) {
1191 /* Skip BAR(5) on ICH8M Apples, system locks up on access. */
1192 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on ICH8M Apples\n"));
1195 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1197 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1198 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1202 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1203 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1205 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1206 chan
= &deviceExtension
->chan
[c
];
1208 if(ChipFlags
& ICH5
) {
1209 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1210 if ((tmp8
& 0x04) == 0) {
1211 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1212 } else if ((tmp8
& 0x02) == 0) {
1215 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1217 } else if ((tmp8
& 0x02) != 0) {
1220 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1224 if(ChipFlags
& I6CH2
) {
1225 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1226 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1228 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1229 switch(tmp8
& 0x03) {
1246 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1247 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1250 if(!(ChipFlags
& ICH7
) && BaseMemAddress
) {
1251 KdPrint2((PRINT_PREFIX
"BaseMemAddress[5] -> indexed\n"));
1252 chan
->RegTranslation
[IDX_INDEXED_ADDR
].Addr
= BaseMemAddress
+ 0;
1253 chan
->RegTranslation
[IDX_INDEXED_ADDR
].MemIo
= MemIo
;
1254 chan
->RegTranslation
[IDX_INDEXED_DATA
].Addr
= BaseMemAddress
+ 4;
1255 chan
->RegTranslation
[IDX_INDEXED_DATA
].MemIo
= MemIo
;
1257 if((ChipFlags
& ICH5
) || BaseMemAddress
) {
1259 KdPrint2((PRINT_PREFIX
"io proc()\n"));
1260 // Rather interesting way of register access...
1261 ChipType
= INTEL_IDX
;
1262 deviceExtension
->HwFlags
&= ~CHIPTYPE_MASK
;
1263 deviceExtension
->HwFlags
|= ChipType
;
1265 if(ChipFlags
& ICH7
) {
1266 KdPrint2((PRINT_PREFIX
"ICH7 way\n"));
1268 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= 0x200*c
+ 0; // this is fake non-zero value
1269 chan
->RegTranslation
[IDX_SATA_SStatus
].Proc
= 1;
1270 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= 0x200*c
+ 2; // this is fake non-zero value
1271 chan
->RegTranslation
[IDX_SATA_SError
].Proc
= 1;
1272 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= 0x200*c
+ 1; // this is fake non-zero value
1273 chan
->RegTranslation
[IDX_SATA_SControl
].Proc
= 1;
1279 // rest of INIT staff is in AtapiChipInit()
1284 /* Cyrix 5530 ATA33 controller */
1285 if(deviceExtension
->DevID
== 0x01021078) {
1286 ConfigInfo
->AlignmentMask
= 0x0f;
1287 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
1290 case ATA_JMICRON_ID
:
1291 /* New JMicron PATA controllers */
1292 GetPciConfig1(0xdf, tmp8
);
1294 KdPrint((" Check JMicron AHCI\n"));
1295 if(Ata_is_ahci_dev(pciData
)) {
1296 ChipFlags
|= UNIATA_AHCI
;
1297 deviceExtension
->HwFlags
|= UNIATA_AHCI
;
1299 KdPrint((" JMicron PATA\n"));
1302 /* set controller configuration to a combined setup we support */
1303 SetPciConfig4(0x40, 0x80c0a131);
1304 SetPciConfig4(0x80, 0x01200000);
1305 //KdPrint((" JMicron Combined (not supported yet)\n"));
1306 //return STATUS_NOT_FOUND;
1311 return STATUS_SUCCESS
;
1313 } // end UniataChipDetect()
1317 Do some 'magic staff' for VIA SouthBridge
1318 This will prevent data losses
1322 AtapiViaSouthBridgeFixup(
1323 IN PVOID HwDeviceExtension
,
1324 IN BUS_DATA_TYPE BusDataType
,
1325 IN ULONG SystemIoBusNumber
,
1329 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1330 PCI_COMMON_CONFIG pciData
;
1336 PCI_SLOT_NUMBER slotData
;
1338 BOOLEAN found
= FALSE
;
1340 slotData
.u
.AsULONG
= slotNumber
;
1341 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1343 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1345 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1350 PCI_COMMON_HDR_LENGTH
);
1352 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1356 VendorID
= pciData
.VendorID
;
1357 DeviceID
= pciData
.DeviceID
;
1358 dev_id
= (VendorID
| (DeviceID
<< 16));
1360 if (dev_id
== 0x03051106 || /* VIA VT8363 */
1361 dev_id
== 0x03911106 || /* VIA VT8371 */
1362 dev_id
== 0x31021106 || /* VIA VT8662 */
1363 dev_id
== 0x31121106) { /* VIA VT8361 */
1366 GetPciConfig1(0x76, reg76
);
1368 if ((reg76
& 0xf0) != 0xd0) {
1369 SetPciConfig1(0x75, 0x80);
1370 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
1377 deviceExtension
->HwFlags
&= ~VIABUG
;
1379 } // end AtapiViaSouthBridgeFixup()
1382 Do some 'magic staff' for ROSB SouthBridge
1383 This will prevent data losses
1387 AtapiRosbSouthBridgeFixup(
1388 IN PVOID HwDeviceExtension
,
1389 IN BUS_DATA_TYPE BusDataType
,
1390 IN ULONG SystemIoBusNumber
,
1394 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1395 PCI_COMMON_CONFIG pciData
;
1401 PCI_SLOT_NUMBER slotData
;
1403 // BOOLEAN found = FALSE;
1405 /* locate the ISA part in the southbridge and enable UDMA33 */
1406 slotData
.u
.AsULONG
= slotNumber
;
1407 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1409 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1411 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1416 PCI_COMMON_HDR_LENGTH
);
1418 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1422 VendorID
= pciData
.VendorID
;
1423 DeviceID
= pciData
.DeviceID
;
1424 dev_id
= (VendorID
| (DeviceID
<< 16));
1426 if (dev_id
== ATA_ROSB4_ISA
) { /* */
1427 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1431 } // end AtapiRosbSouthBridgeFixup()
1434 Do some 'magic staff' for ROSB SouthBridge
1435 This will prevent data losses
1439 AtapiAliSouthBridgeFixup(
1440 IN PVOID HwDeviceExtension
,
1441 IN BUS_DATA_TYPE BusDataType
,
1442 IN ULONG SystemIoBusNumber
,
1443 IN ULONG slotNumber
,
1447 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1448 PCI_COMMON_CONFIG pciData
;
1454 PCI_SLOT_NUMBER slotData
;
1456 // BOOLEAN found = FALSE;
1458 /* workaround for datacorruption bug found on at least SUN Blade-100
1459 * find the ISA function on the southbridge and disable then enable
1460 * the ATA channel tristate buffer */
1461 slotData
.u
.AsULONG
= slotNumber
;
1462 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1464 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1466 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1471 PCI_COMMON_HDR_LENGTH
);
1473 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1477 VendorID
= pciData
.VendorID
;
1478 DeviceID
= pciData
.DeviceID
;
1479 dev_id
= (VendorID
| (DeviceID
<< 16));
1481 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1482 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1483 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1487 } // end AtapiRosbSouthBridgeFixup()
1492 IN PHW_DEVICE_EXTENSION deviceExtension
,
1493 IN ULONG channel
// physical channel number (0-1)
1496 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1497 ULONG slotNumber
= deviceExtension
->slotNumber
;
1498 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1500 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1502 UCHAR reg
, val
, res
;
1503 PCI_SLOT_NUMBER slotData
;
1505 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1507 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1508 reg
= channel
? 0x57 : 0x53;
1509 GetPciConfig1(reg
, val
);
1510 SetPciConfig1(reg
, val
| 0x80);
1514 GetPciConfig1(reg
, val
);
1515 SetPciConfig1(reg
, val
& 0xfe);
1517 GetPciConfig1(0x5a, res
);
1518 res
= res
& (channel
? 0x01 : 0x02);
1519 SetPciConfig1(reg
, val
);
1520 KdPrint2((PRINT_PREFIX
"hpt_cable80(%d) = %d\n", channel
, !res
));
1522 } // end hpt_cable80()
1528 IN PHW_DEVICE_EXTENSION deviceExtension,
1529 IN ULONG channel // physical channel number (0-1)
1532 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1533 ULONG slotNumber = deviceExtension->slotNumber;
1534 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1536 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1543 GetPciConfig1(0x50, reg50);
1560 for (j=0; j>=2; i -= 8) {
1561 i = (3-(channel*2+j))*8;
1562 if (((reg50 >> (i & 0x10)) & 8) &&
1563 ((reg50 >> i) & 0x20) &&
1564 (((reg50 >> i) & 7) < a)) {
1566 res |= TRUE; //(1 << (1 - (i >> 4)));
1569 KdPrint2((PRINT_PREFIX "via_cable80(%d) = %d\n", channel, res));
1572 } // end via_cable80()
1578 IN PHW_DEVICE_EXTENSION deviceExtension
,
1579 IN ULONG channel
, // physical channel number (0-1)
1584 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1585 ULONG slotNumber
= deviceExtension
->slotNumber
;
1586 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1588 if(deviceExtension
->MaxTransferMode
<= ATA_UDMA2
) {
1589 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) <= UDMA2\n", channel
, pci_reg
, bit_offs
));
1593 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1595 ULONG c
; // logical channel (for Compatible Mode controllers)
1598 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1599 chan
= &deviceExtension
->chan
[c
];
1601 GetPciConfig1(pci_reg
, tmp8
);
1602 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1603 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1604 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 0\n", channel
, pci_reg
, bit_offs
));
1608 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 1\n", channel
, pci_reg
, bit_offs
));
1610 } // end generic_cable80()
1614 UniAtaReadLunConfig(
1615 IN PHW_DEVICE_EXTENSION deviceExtension
,
1616 IN ULONG channel
, // physical channel
1617 IN ULONG DeviceNumber
1622 PHW_LU_EXTENSION LunExt
;
1625 c
= channel
- deviceExtension
->Channel
; // logical channel
1627 chan
= &deviceExtension
->chan
[c
];
1628 DeviceNumber
= (DeviceNumber
% deviceExtension
->NumberLuns
);
1629 LunExt
= chan
->lun
[DeviceNumber
];
1631 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadCacheEnable", 1);
1632 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1634 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"WriteCacheEnable", 1);
1635 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1637 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1638 LunExt
->opt_MaxTransferMode
= tmp32
;
1640 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"PreferedTransferMode", 0xffffffff);
1641 LunExt
->opt_PreferedTransferMode
= tmp32
;
1643 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"AdvancedPowerMode", ATA_C_F_APM_CNT_MIN_NO_STANDBY
);
1645 tmp32
= 0xfe; // max. performance
1647 LunExt
->opt_AdvPowerMode
= (UCHAR
)tmp32
;
1649 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"AcousticMgmt", ATA_C_F_AAM_CNT_MAX_POWER_SAVE
);
1651 tmp32
= 0xfe; // max. performance
1654 tmp32
= 0x0; // disable feature
1656 LunExt
->opt_AcousticMode
= (UCHAR
)tmp32
;
1658 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"StandbyTimer", 0);
1662 LunExt
->opt_StandbyTimer
= (UCHAR
)tmp32
;
1664 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadOnly", 0);
1666 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1669 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"GeomType", 0xffffffff);
1670 if(tmp32
> GEOM_MANUAL
) {
1673 LunExt
->opt_GeomType
= tmp32
;
1674 if(tmp32
== GEOM_MANUAL
) {
1675 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1676 LunExt
->opt_GeomType
= GEOM_ORIG
;
1677 // assume IdentifyData is already zero-filled
1678 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"C", 0);
1679 LunExt
->IdentifyData
.NumberOfCurrentCylinders
=
1680 LunExt
->IdentifyData
.NumberOfCylinders
= (USHORT
)tmp32
;
1681 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"H", 0);
1682 LunExt
->IdentifyData
.NumberOfCurrentHeads
=
1683 LunExt
->IdentifyData
.NumberOfHeads
= (USHORT
)tmp32
;
1684 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"S", 0);
1685 LunExt
->IdentifyData
.CurrentSectorsPerTrack
=
1686 LunExt
->IdentifyData
.SectorsPerTrack
= (USHORT
)tmp32
;
1687 memcpy(LunExt
->IdentifyData
.ModelNumber
, "SEIDH DD", 8); // ESDI HDD
1688 memcpy(LunExt
->IdentifyData
.SerialNumber
, ".10", 4);
1689 memcpy(LunExt
->IdentifyData
.FirmwareRevision
, ".10", 4);
1690 if(!LunExt
->IdentifyData
.SectorsPerTrack
||
1691 !LunExt
->IdentifyData
.NumberOfCylinders
||
1692 !LunExt
->IdentifyData
.NumberOfHeads
) {
1694 KdPrint2((PRINT_PREFIX
"Wrong CHS\n"));
1695 LunExt
->opt_GeomType
= GEOM_AUTO
;
1697 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1698 LunExt
->opt_GeomType
= GEOM_ORIG
;
1702 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"Hidden", 0);
1704 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1709 } // end UniAtaReadLunConfig()
1713 AtapiReadChipConfig(
1714 IN PVOID HwDeviceExtension
,
1715 IN ULONG DeviceNumber
,
1716 IN ULONG channel
// physical channel
1719 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1722 ULONG c
; // logical channel (for Compatible Mode controllers)
1725 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1726 ASSERT(deviceExtension
);
1728 if(channel
!= CHAN_NOT_SPECIFIED
) {
1729 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1731 c
= CHAN_NOT_SPECIFIED
;
1734 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1736 if(channel
== CHAN_NOT_SPECIFIED
) {
1737 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1738 deviceExtension
->simplexOnly
= TRUE
;
1740 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1741 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1742 deviceExtension
->opt_AtapiDmaRawRead
= g_opt_AtapiDmaRawRead
;
1743 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1746 if(c
== CHAN_NOT_SPECIFIED
) {
1747 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1748 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1749 chan
= &deviceExtension
->chan
[c
];
1750 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1751 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1752 if(tmp32
!= 0xffffffff) {
1753 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1754 chan
->MaxTransferMode
= tmp32
;
1756 //UniAtaReadLunConfig(deviceExtension, c, 0);
1757 //UniAtaReadLunConfig(deviceExtension, c, 1);
1760 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1761 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1764 deviceExtension
->opt_AtapiDmaControlCmd
=
1765 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1768 deviceExtension
->opt_AtapiDmaRawRead
=
1769 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1772 deviceExtension
->opt_AtapiDmaReadWrite
=
1773 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1777 chan
= &deviceExtension
->chan
[c
];
1778 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1779 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1780 if(tmp32
!= 0xffffffff) {
1781 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1782 chan
->MaxTransferMode
= tmp32
;
1784 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1785 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1787 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1788 UniAtaReadLunConfig(deviceExtension
, channel
, i
);
1793 } // end AtapiReadChipConfig()
1798 IN PVOID HwDeviceExtension
,
1799 IN ULONG DeviceNumber
,
1800 IN ULONG channel
// logical channel
1803 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1804 ULONG slotNumber
= deviceExtension
->slotNumber
;
1805 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1806 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1807 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1808 ULONG RevID
= deviceExtension
->RevID
;
1810 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1811 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1812 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1817 ULONG c
; // logical channel (for Compatible Mode controllers)
1818 BOOLEAN CheckCable
= FALSE
;
1819 BOOLEAN GlobalInit
= FALSE
;
1820 //ULONG BaseIoAddress;
1823 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1826 case CHAN_NOT_SPECIFIED
:
1827 c
= CHAN_NOT_SPECIFIED
;
1831 //c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1833 channel
+= deviceExtension
->Channel
;
1836 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d, c %d\n", DeviceNumber
, channel
, c
));
1838 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1839 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1841 if(deviceExtension
->UnknownDev
) {
1842 KdPrint2((PRINT_PREFIX
" Unknown chip\n" ));
1844 VendorID
= 0xffffffff;
1848 if(ChipFlags
& UNIATA_AHCI
) {
1849 /* if BAR(5) is IO it should point to SATA interface registers */
1850 if(!deviceExtension
->BaseIoAHCI_0
.Addr
) {
1851 KdPrint2((PRINT_PREFIX
" !BaseIoAHCI_0, exiting\n" ));
1854 if(c
== CHAN_NOT_SPECIFIED
) {
1855 return UniataAhciInit(HwDeviceExtension
);
1857 if(c
<deviceExtension
->NumberChannels
) {
1858 KdPrint2((PRINT_PREFIX
" AHCI single channel init\n" ));
1859 UniataAhciReset(HwDeviceExtension
, c
);
1862 KdPrint2((PRINT_PREFIX
" AHCI non-existent channel\n" ));
1867 if((WinVer_Id() > WinVer_NT
) &&
1869 deviceExtension
->MasterDev
) {
1870 PCI_COMMON_CONFIG pciData
;
1873 KdPrint2((PRINT_PREFIX
" re-enable IO resources of MasterDev\n" ));
1875 busDataRead
= HalGetBusData
1876 //ScsiPortGetBusData
1878 //HwDeviceExtension,
1879 PCIConfiguration
, SystemIoBusNumber
, slotNumber
,
1880 &pciData
, PCI_COMMON_HDR_LENGTH
);
1881 if(busDataRead
== PCI_COMMON_HDR_LENGTH
) {
1882 UniataEnableIoPCI(SystemIoBusNumber
, slotNumber
, &pciData
);
1884 KdPrint2((PRINT_PREFIX
" re-enable IO resources of MasterDev FAILED\n" ));
1889 // case ATA_ACARD_ID:
1891 case ATA_ACER_LABS_ID
:
1892 if(ChipFlags
& UNIATA_SATA
) {
1893 if(c
== CHAN_NOT_SPECIFIED
) {
1894 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1895 chan
= &deviceExtension
->chan
[c
];
1896 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1897 /* the southbridge might need the data corruption fix */
1898 if(RevID
== 0xc2 || RevID
== 0xc3) {
1899 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1900 SystemIoBusNumber
, slotNumber
, c
);
1903 /* enable PCI interrupt */
1904 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1907 if(ChipFlags
& ALINEW
) {
1908 if(c
== CHAN_NOT_SPECIFIED
) {
1909 /* use device interrupt as byte count end */
1910 ChangePciConfig1(0x4a, (a
| 0x20));
1911 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
1913 ChangePciConfig1(0x4b, (a
| 0x09));
1916 /* enable ATAPI UDMA mode */
1917 ChangePciConfig1(0x53, (a
| (RevID
>= 0xc7 ? 0x03 : 0x01)));
1920 // check 80-pin cable
1921 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
1924 if(c
== CHAN_NOT_SPECIFIED
) {
1925 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1926 ChangePciConfig1(0x53, (a
| 0x03));
1929 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1934 if(c
== CHAN_NOT_SPECIFIED
) {
1935 /* set prefetch, postwrite */
1936 if(ChipFlags
& AMDBUG
) {
1937 ChangePciConfig1(0x41, (a
& 0x0f));
1939 ChangePciConfig1(0x41, (a
| 0xf0));
1942 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1944 // check 80-pin cable
1945 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
1946 if(c
== CHAN_NOT_SPECIFIED
) {
1949 generic_cable80(deviceExtension
, channel
, 0x42, 0);
1953 case ATA_HIGHPOINT_ID
:
1955 if(c
== CHAN_NOT_SPECIFIED
) {
1957 if(ChipFlags
& HPTOLD
) {
1958 /* turn off interrupt prediction */
1959 ChangePciConfig1(0x51, (a
& ~0x80));
1961 /* turn off interrupt prediction */
1962 ChangePciConfig1(0x51, (a
& ~0x03));
1963 ChangePciConfig1(0x55, (a
& ~0x03));
1964 /* turn on interrupts */
1965 ChangePciConfig1(0x5a, (a
& ~0x10));
1966 /* set clocks etc */
1967 if(ChipType
< HPT372
) {
1968 SetPciConfig1(0x5b, 0x22);
1970 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
1975 // check 80-pin cable
1976 chan
= &deviceExtension
->chan
[c
];
1977 if(!hpt_cable80(deviceExtension
, channel
)) {
1978 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1982 case ATA_INTEL_ID
: {
1986 if(ChipFlags
& UNIATA_SATA
) {
1988 KdPrint2((PRINT_PREFIX
"Intel SATA\n"));
1989 if(ChipFlags
& UNIATA_AHCI
) {
1990 KdPrint2((PRINT_PREFIX
"Do nothing for AHCI\n"));
1993 if(c
== CHAN_NOT_SPECIFIED
) {
1994 KdPrint2((PRINT_PREFIX
"Base init\n"));
1995 /* force all ports active "the legacy way" */
1996 ChangePciConfig2(0x92, (a
| 0x0f));
1998 if(deviceExtension
->BaseIoAddressSATA_0
.Addr
&& (ChipFlags
& ICH7
)) {
1999 /* Set SCRAE bit to enable registers access. */
2000 ChangePciConfig4(0x94, (a
| (1 << 9)));
2001 /* Set Ports Implemented register bits. */
2002 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x0c,
2003 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x0c) | 0x0f);
2005 /* enable PCI interrupt */
2006 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2010 KdPrint2((PRINT_PREFIX
"channel init\n"));
2012 GetPciConfig1(0x90, tmp8
);
2013 KdPrint2((PRINT_PREFIX
"reg 90: %x, init lun map\n", tmp8
));
2015 KdPrint2((PRINT_PREFIX
"chan %d\n", c
));
2016 chan
= &deviceExtension
->chan
[c
];
2018 if(ChipFlags
& ICH5
) {
2019 KdPrint2((PRINT_PREFIX
"ICH5\n"));
2020 if ((tmp8
& 0x04) == 0) {
2021 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2022 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ^ c
;
2023 chan
->lun
[1]->SATA_lun_map
= 0;
2024 } else if ((tmp8
& 0x02) == 0) {
2026 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
2027 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
2030 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2032 } else if ((tmp8
& 0x02) != 0) {
2034 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
2035 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
2038 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
2042 if(ChipFlags
& I6CH2
) {
2043 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
2044 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
2045 chan
->lun
[0]->SATA_lun_map
= c
? 0 : 1;
2046 chan
->lun
[1]->SATA_lun_map
= 0;
2048 KdPrint2((PRINT_PREFIX
"other Intel\n"));
2049 switch(tmp8
& 0x03) {
2051 KdPrint2((PRINT_PREFIX
"0 -> %d/%d\n", 0+c
, 2+c
));
2052 chan
->lun
[0]->SATA_lun_map
= 0+c
;
2053 chan
->lun
[1]->SATA_lun_map
= 2+c
;
2057 KdPrint2((PRINT_PREFIX
"2 -> %d/%d\n", 0, 2));
2058 chan
->lun
[0]->SATA_lun_map
= 0;
2059 chan
->lun
[1]->SATA_lun_map
= 2;
2062 KdPrint2((PRINT_PREFIX
"PATA\n"));
2068 KdPrint2((PRINT_PREFIX
"2 -> %d/%d\n", 1, 3));
2069 chan
->lun
[0]->SATA_lun_map
= 1;
2070 chan
->lun
[1]->SATA_lun_map
= 3;
2073 KdPrint2((PRINT_PREFIX
"PATA\n"));
2081 KdPrint2((PRINT_PREFIX
"PATA part\n"));
2082 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2085 if(ChipType
== INTEL_IDX
) {
2086 KdPrint2((PRINT_PREFIX
"io indexed\n"));
2087 //for(c=0; c<deviceExtension->NumberChannels; c++) {
2088 chan
= &deviceExtension
->chan
[c
];
2089 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2090 if(!(chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
)) {
2091 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 1);
2099 if(deviceExtension
->MaxTransferMode
<= ATA_UDMA2
)
2101 // check 80-pin cable
2102 if(c
== CHAN_NOT_SPECIFIED
) {
2105 chan
= &deviceExtension
->chan
[c
];
2106 GetPciConfig2(0x54, reg54
);
2107 KdPrint2((PRINT_PREFIX
" intel 80-pin check (reg54=%x)\n", reg54
));
2108 if(reg54
== 0x0000 || reg54
== 0xffff) {
2109 KdPrint2((PRINT_PREFIX
" check failed (not supported)\n"));
2111 if( ((reg54
>> (channel
*2)) & 30) == 0) {
2112 KdPrint2((PRINT_PREFIX
" intel 40-pin\n"));
2113 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2117 case ATA_NVIDIA_ID
: {
2118 if(ChipFlags
& UNIATA_SATA
) {
2119 if(c
== CHAN_NOT_SPECIFIED
) {
2120 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
2121 /* enable control access */
2122 ChangePciConfig1(0x50, (a
| 0x04));
2123 /* MCP55 seems to need some time to allow r_res2 read. */
2124 AtapiStallExecution(10);
2125 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
2126 if(ChipFlags
& NVQ
) {
2127 /* clear interrupt status */
2128 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
2129 /* enable device and PHY state change interrupts */
2130 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
2131 /* disable NCQ support */
2132 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
2133 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
2135 /* clear interrupt status */
2136 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
2137 /* enable device and PHY state change interrupts */
2138 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
2140 /* enable PCI interrupt */
2141 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2143 //UniataSataPhyEnable(HwDeviceExtension, c);
2148 if(c
== CHAN_NOT_SPECIFIED
) {
2149 /* set prefetch, postwrite */
2150 ChangePciConfig1(0x51, (a
& 0x0f));
2152 // check 80-pin cable
2153 generic_cable80(deviceExtension
, channel
, 0x52, 1);
2154 /* chan = &deviceExtension->chan[c];
2155 GetPciConfig1(0x52, reg52);
2156 if( !((reg52 >> (channel*2)) & 0x01)) {
2157 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2162 case ATA_PROMISE_ID
: {
2167 if(c
== CHAN_NOT_SPECIFIED
) {
2168 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
2169 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
2170 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
2174 /* enable burst mode */
2175 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
2176 if(c
== CHAN_NOT_SPECIFIED
) {
2177 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
2178 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
2180 // check 80-pin cable
2181 chan
= &deviceExtension
->chan
[c
];
2182 GetPciConfig2(0x50, Reg50
);
2183 if(Reg50
& (1 << (channel
+10))) {
2184 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2189 if(c
== CHAN_NOT_SPECIFIED
) {
2192 // check 80-pin cable
2193 chan
= &deviceExtension
->chan
[c
];
2194 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
2195 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
2196 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2201 if(c
== CHAN_NOT_SPECIFIED
) {
2202 /* clear SATA status and unmask interrupts */
2203 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),
2204 (ChipFlags
& PRG2
) ? 0x60 : 0x6c, 0x000000ff);
2205 if(ChipFlags
& UNIATA_SATA
) {
2206 /* enable "long burst length" on gen2 chips */
2207 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
), 0x44,
2208 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
), 0x44) | 0x2000);
2211 chan
= &deviceExtension
->chan
[c
];
2212 AtapiWritePort4(chan
, IDX_BM_Command
,
2213 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
2214 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
2215 // check 80-pin cable
2216 if(chan
->MaxTransferMode
< ATA_SA150
&&
2217 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
2218 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2224 case ATA_SERVERWORKS_ID
:
2225 if(c
== CHAN_NOT_SPECIFIED
) {
2226 if(ChipType
== SWKS33
) {
2227 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2228 SystemIoBusNumber
, slotNumber
);
2230 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
2235 if(ChipType
== SIIMIO
) {
2236 KdPrint2((PRINT_PREFIX
"ATI New\n"));
2239 KdPrint2((PRINT_PREFIX
"ATI\n"));
2243 case ATA_SILICON_IMAGE_ID
:
2244 /* if(ChipFlags & SIIENINTR) {
2245 SetPciConfig1(0x71, 0x01);
2250 KdPrint2((PRINT_PREFIX
"SII\n"));
2253 if(c
== CHAN_NOT_SPECIFIED
) {
2254 if(ChipFlags
& SIISETCLK
) {
2255 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
2256 GetPciConfig1(0x8a, tmp8
);
2257 if ((tmp8
& 0x30) != 0x10)
2258 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
2259 GetPciConfig1(0x8a, tmp8
);
2260 if ((tmp8
& 0x30) != 0x10) {
2261 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
2262 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2266 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
2267 // check 80-pin cable
2268 if(c
== CHAN_NOT_SPECIFIED
) {
2271 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
2272 chan
= &deviceExtension
->chan
[c
];
2273 GetPciConfig2(0x79, Reg79
);
2274 if(Reg79
& (channel
? 0x02 : 0x01)) {
2275 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2279 ULONG unit01
= (c
& 1);
2280 ULONG unit10
= (c
& 2);
2281 /* enable/disable PHY state change interrupt */
2282 if(c
== CHAN_NOT_SPECIFIED
) {
2283 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2286 if(ChipFlags
& SIINOSATAIRQ
) {
2287 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2288 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2292 if(ChipFlags
& SIINOSATAIRQ
) {
2293 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2294 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2296 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
2297 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
2301 if(c
== CHAN_NOT_SPECIFIED
) {
2302 /* enable interrupt as BIOS might not */
2303 ChangePciConfig1(0x8a, (a
& 0x3f));
2304 // Enable 3rd and 4th channels
2305 if (ChipFlags
& SII4CH
) {
2306 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
2307 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
2310 chan
= &deviceExtension
->chan
[c
];
2311 /* dont block interrupts */
2312 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2313 /*tmp32 =*/ AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2314 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
2316 /*tmp32 =*/ AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2318 /* Initialize FIFO PCI bus arbitration */
2319 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
2321 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp8
));
2323 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
2325 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
2332 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
2333 if(c
== CHAN_NOT_SPECIFIED
) {
2334 /* Setup interrupts. */
2335 SetPciConfig1(0x71, 0x01);
2337 /* GetPciConfig1(0x8a, tmp8);
2339 SetPciConfig1(0x71, tmp8);*/
2341 /* Use MEMORY READ LINE for reads.
2342 * NOTE: Although not mentioned in the PCI0646U specs,
2343 * these bits are write only and won't be read
2344 * back as set or not. The PCI0646U2 specs clarify
2348 SetPciConfig1(0x71, tmp8);
2350 /* Set reasonable active/recovery/address-setup values. */
2351 SetPciConfig1(0x53, 0x40);
2352 SetPciConfig1(0x54, 0x3f);
2353 SetPciConfig1(0x55, 0x40);
2354 SetPciConfig1(0x56, 0x3f);
2355 SetPciConfig1(0x57, 0x1c);
2356 SetPciConfig1(0x58, 0x3f);
2357 SetPciConfig1(0x5b, 0x3f);
2362 KdPrint2((PRINT_PREFIX
"ATI700\n"));
2363 if(c
== 0 && !(ChipFlags
& UNIATA_AHCI
)) {
2364 KdPrint2((PRINT_PREFIX
"IXP700 PATA\n"));
2365 chan
= &deviceExtension
->chan
[c
];
2366 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2369 } /* switch(ChipType) */
2372 if(c
== CHAN_NOT_SPECIFIED
) {
2378 ChangePciConfig1(0x52, (a
& ~0x04));
2382 ChangePciConfig1(0x49, (a
& ~0x01));
2385 ChangePciConfig2(0x50, (a
| 0x0008));
2386 ChangePciConfig2(0x52, (a
| 0x0008));
2389 ChangePciConfig2(0x04, (a
& ~0x0400));
2393 if(ChipType
== SIS133NEW
) {
2395 // check 80-pin cable
2396 if(c
== CHAN_NOT_SPECIFIED
) {
2399 chan
= &deviceExtension
->chan
[c
];
2400 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
2401 if(tmp16
& 0x8000) {
2402 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2406 // check 80-pin cable
2407 if(c
== CHAN_NOT_SPECIFIED
) {
2410 chan
= &deviceExtension
->chan
[c
];
2411 GetPciConfig1(48, tmp8
);
2412 if(tmp8
& (0x10 << channel
)) {
2413 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2420 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2423 if(c
== CHAN_NOT_SPECIFIED
) {
2424 /* prepare for ATA-66 on the 82C686a and 82C596b */
2425 if(ChipFlags
& VIACLK
) {
2426 ChangePciConfig4(0x50, (a
| 0x030b030b));
2429 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2430 /* enable PCI interrupt */
2431 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
2434 * vt6420/1 has problems talking to some drives. The following
2435 * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
2437 * When host issues HOLD, device may send up to 20DW of data
2438 * before acknowledging it with HOLDA and the host should be
2439 * able to buffer them in FIFO. Unfortunately, some WD drives
2440 * send upto 40DW before acknowledging HOLD and, in the
2441 * default configuration, this ends up overflowing vt6421's
2442 * FIFO, making the controller abort the transaction with
2445 * Rx52[2] is the internal 128DW FIFO Flow control watermark
2446 * adjusting mechanism enable bit and the default value 0
2447 * means host will issue HOLD to device when the left FIFO
2448 * size goes below 32DW. Setting it to 1 makes the watermark
2451 * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
2454 if(DeviceID
== 0x3149 || DeviceID
== 0x3249) { //vt6420 or vt6421
2455 KdPrint2((PRINT_PREFIX
"VIA 642x FIFO\n"));
2456 ChangePciConfig1(0x52, a
| (1 << 2));
2462 /* the southbridge might need the data corruption fix */
2463 if(ChipFlags
& VIABUG
) {
2464 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2465 SystemIoBusNumber
, slotNumber
);
2467 /* set prefetch, postwrite */
2468 if(ChipType
!= VIA133
) {
2469 ChangePciConfig1(0x41, (a
| 0xf0));
2472 /* set fifo configuration half'n'half */
2473 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
2475 /* set status register read retry */
2476 ChangePciConfig1(0x44, (a
| 0x08));
2478 /* set DMA read & end-of-sector fifo flush */
2479 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
2481 /* set sector size */
2482 SetPciConfig2(0x60, DEV_BSIZE
);
2483 SetPciConfig2(0x68, DEV_BSIZE
);
2486 chan
= &deviceExtension
->chan
[c
];
2488 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2489 if((ChipFlags
& VIABAR
) && (c
>= 2)) {
2490 // this is PATA channel
2491 chan
->MaxTransferMode
= ATA_UDMA5
;
2494 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2498 // check 80-pin cable
2499 if(!via_cable80(deviceExtension, channel)) {
2500 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2508 if(ChipType
== ITE_33
|| ChipType
== ITE_133_NEW
) {
2511 if(ChipType
== ITE_133
) {
2512 if(c
== CHAN_NOT_SPECIFIED
) {
2513 /* set PCI mode and 66Mhz reference clock */
2514 ChangePciConfig1(0x50, a
& ~0x83);
2516 /* set default active & recover timings */
2517 SetPciConfig1(0x54, 0x31);
2518 SetPciConfig1(0x56, 0x31);
2520 // check 80-pin cable
2521 GetPciConfig2(0x40, tmp16
);
2522 chan
= &deviceExtension
->chan
[c
];
2523 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
2524 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2528 if(ChipType
== ITE_133_NEW
) {
2532 if(c
!= CHAN_NOT_SPECIFIED
) {
2533 // We don't know how to check for 80-pin cable on unknown controllers.
2534 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2535 // So, leave this flag to use as hint in error recovery procedures
2536 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
2537 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
2542 // In all places separate channels are inited after common controller init
2543 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2544 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
2545 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2546 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
2551 } // end AtapiChipInit()
2556 IN PHW_DEVICE_EXTENSION deviceExtension
,
2557 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
2565 if(!BaseIoAddressBM_0
) {
2568 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2569 chan
= &deviceExtension
->chan
[c
];
2570 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
2571 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONGIO_PTR
)BaseIoAddressBM_0
+ i
) : 0;
2572 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
2574 if(BaseIoAddressBM_0
) {
2575 BaseIoAddressBM_0
++;
2579 } // end UniataInitMapBM()
2584 IN PHW_CHANNEL chan
,
2585 IN PIDE_REGISTERS_1 BaseIoAddress1
,
2586 IN PIDE_REGISTERS_2 BaseIoAddress2
2591 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
2592 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONGIO_PTR
)BaseIoAddress1
+ i
) : 0;
2593 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
2595 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
2596 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONGIO_PTR
)BaseIoAddress2
+ i
) : 0;
2597 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
2599 UniataInitSyncBaseIO(chan
);
2601 } // end UniataInitMapBase()
2605 UniataInitSyncBaseIO(
2609 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
2610 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
2612 } // end UniataInitSyncBaseIO()
2617 IN PHW_CHANNEL chan
,
2618 IN PHW_DEVICE_EXTENSION deviceExtension
,
2624 KdPrint2((PRINT_PREFIX
"AtapiSetupLunPtrs for channel %d of %d, %d luns \n", c
, deviceExtension
->NumberChannels
, deviceExtension
->NumberLuns
));
2626 if(!deviceExtension
->NumberLuns
) {
2627 KdPrint2((PRINT_PREFIX
"Achtung !deviceExtension->NumberLuns \n"));
2628 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
;
2630 KdPrint2((PRINT_PREFIX
" Chan %#x\n", chan
));
2631 chan
->DeviceExtension
= deviceExtension
;
2633 chan
->NumberLuns
= deviceExtension
->NumberLuns
;
2634 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2635 chan
->lun
[i
] = &(deviceExtension
->lun
[c
*deviceExtension
->NumberLuns
+i
]);
2636 KdPrint2((PRINT_PREFIX
" Lun %#x\n", i
));
2637 KdPrint2((PRINT_PREFIX
" Lun ptr %#x\n", chan
->lun
[i
]));
2639 chan
->AltRegMap
= deviceExtension
->AltRegMap
;
2640 chan
->NextDpcChan
= -1;
2641 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2642 chan
->lun
[i
]->DeviceExtension
= deviceExtension
;
2643 chan
->lun
[i
]->chan
= chan
;
2644 chan
->lun
[i
]->Lun
= i
;
2646 if((deviceExtension
->HwFlags
& UNIATA_AHCI
) &&
2647 deviceExtension
->AhciInternalAtaReq0
&&
2648 deviceExtension
->AhciInternalSrb0
) {
2649 chan
->AhciInternalAtaReq
= &(deviceExtension
->AhciInternalAtaReq0
[c
]);
2650 chan
->AhciInternalSrb
= &(deviceExtension
->AhciInternalSrb0
[c
]);
2651 UniataAhciSetupCmdPtr(chan
->AhciInternalAtaReq
);
2652 chan
->AhciInternalSrb
->SrbExtension
= chan
->AhciInternalAtaReq
;
2653 chan
->AhciInternalAtaReq
->Srb
= chan
->AhciInternalSrb
;
2656 } // end AtapiSetupLunPtrs()
2660 UniataAllocateLunExt(
2661 PHW_DEVICE_EXTENSION deviceExtension
,
2662 ULONG NewNumberChannels
2665 PHW_LU_EXTENSION old_luns
= NULL
;
2666 PHW_CHANNEL old_chans
= NULL
;
2668 KdPrint2((PRINT_PREFIX
"allocate %d Luns for %d channels\n", deviceExtension
->NumberLuns
, deviceExtension
->NumberChannels
));
2670 old_luns
= deviceExtension
->lun
;
2671 old_chans
= deviceExtension
->chan
;
2673 if(old_luns
|| old_chans
) {
2674 if(NewNumberChannels
== UNIATA_ALLOCATE_NEW_LUNS
) {
2675 KdPrint2((PRINT_PREFIX
"already allocated!\n"));
2680 if(!deviceExtension
->NumberLuns
) {
2681 KdPrint2((PRINT_PREFIX
"default NumberLuns=2\n"));
2682 deviceExtension
->NumberLuns
= 2;
2685 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2686 if(!deviceExtension
->AhciInternalAtaReq0
) {
2687 deviceExtension
->AhciInternalAtaReq0
= (PATA_REQ
)ExAllocatePool(NonPagedPool
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2688 if (!deviceExtension
->AhciInternalAtaReq0
) {
2689 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalAtaReq0 => SP_RETURN_ERROR\n"));
2692 RtlZeroMemory(deviceExtension
->AhciInternalAtaReq0
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2694 if(!deviceExtension
->AhciInternalSrb0
) {
2695 deviceExtension
->AhciInternalSrb0
= (PSCSI_REQUEST_BLOCK
)ExAllocatePool(NonPagedPool
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2696 if (!deviceExtension
->AhciInternalSrb0
) {
2697 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalSrb0 => SP_RETURN_ERROR\n"));
2698 UniataFreeLunExt(deviceExtension
);
2701 RtlZeroMemory(deviceExtension
->AhciInternalSrb0
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2705 deviceExtension
->lun
= (PHW_LU_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2706 if (!deviceExtension
->lun
) {
2707 KdPrint2((PRINT_PREFIX
"!deviceExtension->lun => SP_RETURN_ERROR\n"));
2708 UniataFreeLunExt(deviceExtension
);
2711 RtlZeroMemory(deviceExtension
->lun
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2713 deviceExtension
->chan
= (PHW_CHANNEL
)ExAllocatePool(NonPagedPool
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2714 if (!deviceExtension
->chan
) {
2715 UniataFreeLunExt(deviceExtension
);
2716 KdPrint2((PRINT_PREFIX
"!deviceExtension->chan => SP_RETURN_ERROR\n"));
2719 RtlZeroMemory(deviceExtension
->chan
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2721 } // end UniataAllocateLunExt()
2726 PHW_DEVICE_EXTENSION deviceExtension
2729 if (deviceExtension
->lun
) {
2730 ExFreePool(deviceExtension
->lun
);
2731 deviceExtension
->lun
= NULL
;
2733 if (deviceExtension
->chan
) {
2734 ExFreePool(deviceExtension
->chan
);
2735 deviceExtension
->chan
= NULL
;
2737 if(deviceExtension
->AhciInternalAtaReq0
) {
2738 ExFreePool(deviceExtension
->AhciInternalAtaReq0
);
2739 deviceExtension
->AhciInternalAtaReq0
= NULL
;
2741 if(deviceExtension
->AhciInternalSrb0
) {
2742 ExFreePool(deviceExtension
->AhciInternalSrb0
);
2743 deviceExtension
->AhciInternalSrb0
= NULL
;
2747 } // end UniataFreeLunExt()