3 Copyright (c) 2004-2011 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
48 UniataChipDetectChannels(
49 IN PVOID HwDeviceExtension
,
50 IN PPCI_COMMON_CONFIG pciData
, // optional
51 IN ULONG DeviceNumber
,
52 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
55 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
56 //ULONG slotNumber = deviceExtension->slotNumber;
57 //ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
58 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
59 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
60 //ULONG RevID = deviceExtension->RevID;
61 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
62 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
64 KdPrint2((PRINT_PREFIX
"UniataChipDetectChannels:\n" ));
66 if(ChipFlags
& (UNIATA_SATA
| UNIATA_AHCI
)) {
67 if(!deviceExtension
->NumberChannels
) {
68 KdPrint2((PRINT_PREFIX
"uninitialized SATA/AHCI port number -> 1\n"));
69 deviceExtension
->NumberChannels
= 1;
71 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhciPM", 1 /* DEBUG */)) {
72 KdPrint2((PRINT_PREFIX
"SATA/AHCI w/o PM, max luns 1\n"));
73 deviceExtension
->NumberLuns
= 2;
74 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
76 KdPrint2((PRINT_PREFIX
"SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS
));
77 deviceExtension
->NumberLuns
= SATA_MAX_PM_UNITS
;
78 //deviceExtension->NumberLuns = 1;
81 if(deviceExtension
->MasterDev
) {
82 KdPrint2((PRINT_PREFIX
"MasterDev -> 1 chan\n"));
83 deviceExtension
->NumberChannels
= 1;
87 case ATA_ACER_LABS_ID
:
88 switch(deviceExtension
->DevID
) {
91 deviceExtension
->NumberChannels
= 4;
92 KdPrint2((PRINT_PREFIX
"Acer 4 chan\n"));
97 if(ChipType
!= PRMIO
) {
100 deviceExtension
->NumberChannels
= 4;
101 KdPrint2((PRINT_PREFIX
"Promise 4 chan\n"));
104 KdPrint2((PRINT_PREFIX
"Marvell\n"));
105 switch(deviceExtension
->DevID
) {
107 /* 88SX6101 only have 1 PATA channel */
108 if(BMList
[deviceExtension
->DevIndex
].channel
) {
109 KdPrint2((PRINT_PREFIX
"88SX6101 has no 2nd PATA chan\n"));
112 deviceExtension
->NumberChannels
= 1;
113 KdPrint2((PRINT_PREFIX
"88SX6101 PATA 1 chan\n"));
118 KdPrint2((PRINT_PREFIX
"ATI\n"));
119 switch(deviceExtension
->DevID
) {
122 /* IXP600 & IXP700 only have 1 PATA channel */
123 if(BMList
[deviceExtension
->DevIndex
].channel
) {
124 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
127 deviceExtension
->NumberChannels
= 1;
128 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
132 case ATA_SILICON_IMAGE_ID
:
134 if(ChipFlags
& SIIBUG
) {
135 /* work around errata in early chips */
136 ConfigInfo
->AlignmentMask
= 0x1fff;
137 deviceExtension
->MaximumDmaTransferLength
= 15 * DEV_BSIZE
;
139 if(ChipType
!= SIIMIO
) {
146 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
147 KdPrint2((PRINT_PREFIX
"New SII\n"));
149 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
151 if(deviceExtension
->HwFlags
& SII4CH
) {
152 deviceExtension
->NumberChannels
= 4;
153 KdPrint2((PRINT_PREFIX
"4 chan\n"));
157 if(/*(deviceExtension->DevID == 0x32491106) &&
158 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)*/
159 deviceExtension
->HwFlags
& VIABAR
) {
160 deviceExtension
->NumberChannels
= 3;
161 KdPrint2((PRINT_PREFIX
"VIA 3 chan\n"));
163 if(ChipFlags
& VIASATA
) {
164 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
165 // do nothing, generic PATA INIT
166 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs -> no PM\n"));
167 deviceExtension
->NumberLuns
= 1;
171 /* ITE ATA133 controller */
172 if(deviceExtension
->DevID
== 0x82131283) {
173 if(BMList
[deviceExtension
->DevIndex
].channel
) {
174 KdPrint2((PRINT_PREFIX
"New ITE has no 2nd PATA chan\n"));
177 deviceExtension
->NumberChannels
= 1;
178 KdPrint2((PRINT_PREFIX
"New ITE PATA 1 chan\n"));
182 /* New Intel PATA controllers */
183 if(g_opt_VirtualMachine
!= VM_VBOX
&&
184 /*deviceExtension->DevID == 0x27df8086 ||
185 deviceExtension->DevID == 0x269e8086 ||
186 deviceExtension->DevID == ATA_I82801HBM*/
188 if(BMList
[deviceExtension
->DevIndex
].channel
) {
189 KdPrint2((PRINT_PREFIX
"New Intel PATA has no 2nd chan\n"));
192 deviceExtension
->NumberChannels
= 1;
193 KdPrint2((PRINT_PREFIX
"New Intel PATA 1 chan\n"));
197 /* New JMicron PATA controllers */
198 if(deviceExtension
->DevID
== ATA_JMB361
||
199 deviceExtension
->DevID
== ATA_JMB363
||
200 deviceExtension
->DevID
== ATA_JMB368
) {
201 if(BMList
[deviceExtension
->DevIndex
].channel
) {
202 KdPrint2((PRINT_PREFIX
"New JMicron has no 2nd chan\n"));
205 deviceExtension
->NumberChannels
= 1;
206 KdPrint2((PRINT_PREFIX
"New JMicron PATA 1 chan\n"));
209 } // end switch(VendorID)
212 } // end UniataChipDetectChannels()
217 IN PVOID HwDeviceExtension
,
218 IN PPCI_COMMON_CONFIG pciData
, // optional
219 IN ULONG DeviceNumber
,
220 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
221 IN BOOLEAN
* simplexOnly
224 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
225 ULONG slotNumber
= deviceExtension
->slotNumber
;
226 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
227 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
228 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
229 ULONG RevID
= deviceExtension
->RevID
;
231 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
237 ULONG BaseMemAddress
;
238 ULONG BaseIoAddress1
;
239 ULONG BaseIoAddress2
;
240 ULONG BaseIoAddressBM
;
241 BOOLEAN MemIo
= FALSE
;
243 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
244 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
246 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
248 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
254 BaseIoAddressBM
= pciData
->u
.type0
.BaseAddresses
[4] & ~0x07;
255 deviceExtension
->MaxTransferMode
= BaseIoAddressBM
? ATA_DMA
: ATA_PIO4
;
256 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
257 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
259 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
260 if(i
!= BMLIST_TERMINATOR
) {
261 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
263 if(Ata_is_ahci_dev(pciData
)) {
264 KdPrint2((PRINT_PREFIX
" AHCI candidate"));
266 deviceExtension
->NumberChannels
= 0;
267 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
268 KdPrint2((PRINT_PREFIX
" AHCI init failed - not detected\n"));
269 return STATUS_UNSUCCESSFUL
;
271 KdPrint2((PRINT_PREFIX
" unknown AHCI dev, addr %#x", deviceExtension
->BaseIoAHCI_0
.Addr
));
274 KdPrint2((PRINT_PREFIX
" unknown dev, BM addr %#I64x", BaseIoAddressBM
));
276 KdPrint2((PRINT_PREFIX
" MaxTransferMode %#x\n", deviceExtension
->MaxTransferMode
));
278 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
279 return STATUS_UNSUCCESSFUL
;
281 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
282 return STATUS_UNSUCCESSFUL
;
285 return STATUS_NOT_FOUND
;
288 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
289 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
290 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
291 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
292 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
293 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
294 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
295 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
297 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
298 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
299 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
300 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
302 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
303 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),*/
304 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
305 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
306 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
307 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
308 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
309 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
311 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
312 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
313 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
315 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
316 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
318 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
319 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
320 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
321 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
322 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
323 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
326 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
327 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
328 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
329 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
330 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
331 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
332 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
333 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
334 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
335 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
336 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
337 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
338 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
339 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| 0x00 ),
340 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| 0x00 ),
341 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
342 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6
, "VIA 8237A" , VIA133
| 0x00 ),
343 // presence of AHCI controller means something about isa-mapped part
344 PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_UDMA6
, "VIA 8237S" , VIA133
| 0x00 ),
345 PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
346 PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
347 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8251" , VIA133
| 0x00 ),
348 PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150
, "VIA CX700" , VIA133
| VIASATA
),
349 PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150
, "VIA VX800" , VIA133
| VIASATA
),
350 PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6
, "VIA VX855" , VIA133
| 0x00 ),
351 PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300
, "VIA VX900" , VIA133
| VIASATA
),
352 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
355 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
356 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH
),
357 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH
),
358 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH
),
359 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH
),
360 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
363 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
368 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
369 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
370 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
371 if(i
!= BMLIST_TERMINATOR
) {
372 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
377 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
378 // New chips have own DeviceId
379 if(deviceExtension
->DevID
!= ATA_VIA82C571
&&
380 deviceExtension
->DevID
!= ATA_VIACX700IDE
&&
381 deviceExtension
->DevID
!= ATA_VIASATAIDE
&&
382 deviceExtension
->DevID
!= ATA_VIASATAIDE2
&&
383 deviceExtension
->DevID
!= ATA_VIASATAIDE3
) {
384 KdPrint2((PRINT_PREFIX
"Via new\n"));
387 KdPrint2((PRINT_PREFIX
"Via-old-style %x\n", deviceExtension
->DevID
));
388 // Traditionally, chips have same DeviceId, we can distinguish between them
389 // only by ISA Bridge DeviceId
390 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
391 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
392 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
393 /* if(i == BMLIST_TERMINATOR) {
394 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
396 if(i
!= BMLIST_TERMINATOR
) {
397 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
398 deviceExtension
->HwFlags
|= VIASOUTH
;
400 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
401 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
402 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
403 if(i
!= BMLIST_TERMINATOR
) {
404 deviceExtension
->FullDevName
= ViaAdapters
[i
].FullDevName
;
414 KdPrint2((PRINT_PREFIX
"Default\n"));
416 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
417 /* do extra chipset specific setups */
418 switch(deviceExtension
->DevID
) {
420 //case ATA_CYPRESS_ID:
421 case 0xc6931080: /* 82c693 ATA controller */
422 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
425 case 0x000116ca: /* Cenatek Rocket Drive controller */
426 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
429 /* case ATA_CYRIX_ID:
430 DevTypeInfo = &CyrixAdapters[0];
432 case 0x01021078: /* Cyrix 5530 ATA33 controller */
433 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
436 case 0x06401039: /* CMD 640 known bad, no DMA */
442 case 0x10001042: /* RZ 100x known bad, no DMA */
445 if(deviceExtension
->BaseIoAddressBM_0
)
446 ScsiPortFreeDeviceBase(HwDeviceExtension
,
447 deviceExtension
->BaseIoAddressBM_0
);
449 deviceExtension
->BaseIoAddressBM_0
= 0;
450 deviceExtension
->BusMaster
= FALSE
;
451 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
454 case 0x81721283: /* IT8172 IDE controller */
455 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
460 return STATUS_NOT_FOUND
;
462 return STATUS_SUCCESS
;
466 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
468 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
469 if(i
== BMLIST_TERMINATOR
) {
471 //return STATUS_NOT_FOUND;
473 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
474 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
476 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
478 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
479 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
480 deviceExtension
->HwFlags
= tmp32
;
482 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
483 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
484 deviceExtension
->HwFlags
|= tmp32
;
486 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
487 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
488 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
492 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
493 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
494 if(tmp32
!= 0xffffffff) {
495 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
496 deviceExtension
->MaxTransferMode
= tmp32
;
499 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
500 deviceExtension
->HwFlags
|= UNIATA_SATA
;
503 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
504 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
506 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
507 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
509 if(ChipFlags
& UNIATA_AHCI
) {
510 deviceExtension
->NumberChannels
= 0;
511 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
512 KdPrint2((PRINT_PREFIX
" AHCI detect failed\n"));
513 return STATUS_UNSUCCESSFUL
;
516 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
517 return STATUS_UNSUCCESSFUL
;
519 // UniataAhciDetect() sets proper number of channels
520 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
521 return STATUS_UNSUCCESSFUL
;
524 if(ChipFlags
& UNIATA_AHCI
) {
528 case ATA_ACER_LABS_ID
:
529 if(ChipFlags
& UNIATA_SATA
) {
530 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
531 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
533 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
535 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
536 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
537 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
538 //ULONG unit01 = (c & 1);
539 ULONG unit10
= (c
& 2);
540 chan
= &deviceExtension
->chan
[c
];
542 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
543 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
545 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
546 UniataInitSyncBaseIO(chan
);
548 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
549 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
552 // SATA not supported yet
554 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
555 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
556 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
558 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
563 if(ChipFlags
& UNIATA_SATA
) {
564 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
565 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
566 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
567 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
568 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
569 KdPrint2((PRINT_PREFIX
"MemIo\n"));
572 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
573 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
574 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
575 chan
= &deviceExtension
->chan
[c
];
577 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
578 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
579 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
580 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
581 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
582 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
584 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
590 if(ChipType
!= PRMIO
) {
596 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
597 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
599 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
600 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
601 KdPrint2((PRINT_PREFIX
"MemIo\n"));
604 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
605 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
606 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
610 chan
= &deviceExtension
->chan
[c
];
615 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
616 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs12
;
617 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
619 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
620 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
622 UniataInitSyncBaseIO(chan
);
624 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
625 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
626 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
627 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
628 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
629 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
634 KdPrint2((PRINT_PREFIX
"ATI\n"));
636 case ATA_SILICON_IMAGE_ID
: {
638 if(ChipFlags
& SIIBUG
) {
640 if(ChipType
!= SIIMIO
) {
647 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
648 KdPrint2((PRINT_PREFIX
"New SII\n"));
650 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
652 //if(deviceExtension->HwFlags & SII4CH) {
653 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
655 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
657 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
658 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
659 KdPrint2((PRINT_PREFIX
"MemIo\n"));
662 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
663 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
665 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
666 ULONG unit01
= (c
& 1);
667 ULONG unit10
= (c
& 2);
669 chan
= &deviceExtension
->chan
[c
];
671 if(deviceExtension
->AltRegMap
) {
672 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
673 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
674 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
676 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
677 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
678 UniataInitSyncBaseIO(chan
);
680 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
681 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
682 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
683 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
684 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
685 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
686 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
687 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
688 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
689 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
690 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
691 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
694 if(ChipFlags
& UNIATA_SATA
) {
695 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
696 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
697 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
698 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
699 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
700 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
702 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
707 case ATA_SERVERWORKS_ID
: {
709 if(ChipType
!= SWKSMIO
) {
716 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
718 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
719 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
721 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
722 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
723 KdPrint2((PRINT_PREFIX
"MemIo\n"));
726 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
727 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
729 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
730 ULONG offs
= c
*0x100;
732 chan
= &deviceExtension
->chan
[c
];
733 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
734 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
735 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
737 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
738 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
739 UniataInitSyncBaseIO(chan
);
741 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
742 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
743 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
744 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
745 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
746 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
748 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
749 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
750 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
751 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
752 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
753 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
755 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
760 //if(ChipType != SIS_SOUTH) {}
761 BOOLEAN SIS_182
=FALSE
;
763 if(!(ChipFlags
& SIS_BASE
)) {
764 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
765 //PrintNtConsole("Found SIS_SOUTH\n");
768 // Make some additional checks
769 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
770 ChangePciConfig1(0x57, (a
& 0x7f));
771 GetPciConfig4(0x00, tmp32
);
772 if(tmp32
== ATA_SIS5518
) {
773 ChipType
= SIS133NEW
;
774 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
775 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
776 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
777 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
779 ChangePciConfig1(0x57, (a
| 0x80));
781 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
782 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
783 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
784 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, -1, NULL
, -1 )
787 GetPciConfig1(0x4a, tmp8
);
788 ChangePciConfig1(0x4a, (a
| 0x10));
789 if(tmp32
== ATA_SIS5513
||
790 tmp32
== ATA_SIS5517
) {
791 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
792 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
793 if(i
!= BMLIST_TERMINATOR
) {
794 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
795 //deviceExtension->MaxTransferMode = ATA_UDMA6;
796 deviceExtension
->MaxTransferMode
= SiSSouthAdapters
[i
].MaxTransferMode
;
797 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
798 deviceExtension
->HwFlags
|= UNIATA_SATA
;
799 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182) {
804 // SiS-South not found
805 if(tmp32
== ATA_SIS5517
) {
806 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
807 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
810 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
815 SetPciConfig1(0x4a, tmp8
);
816 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
817 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
818 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
819 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
821 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
823 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
824 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
825 KdPrint2((PRINT_PREFIX
"MemIo\n"));
828 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
829 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
831 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
832 ULONG offs
= c
<< (SIS_182
? 5 : 6);
834 chan
= &deviceExtension
->chan
[c
];
835 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
836 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
837 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
838 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
839 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
840 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
842 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
846 //ChangePciConfig1(0x57, (a | 0x80));
851 if(ChipFlags
& VIASATA
) {
852 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
853 // do nothing, generic PATA INIT
854 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs\n"));
857 if(ChipFlags
& UNIATA_SATA
) {
860 ULONG BaseMemAddress
= 0;
863 case 0x3149: // VIA 6420
864 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
867 case 0x3249: // VIA 6421
868 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
873 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
874 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
875 5, 0, IoSize
* deviceExtension
->NumberChannels
);
876 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
877 KdPrint2((PRINT_PREFIX
"MemIo\n"));
880 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
881 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
883 if(/*deviceExtension->*/BaseMemAddress
) {
884 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
885 if(ChipFlags
& VIABAR
) {
887 ULONG BaseIoAddressBM_0
;
890 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
891 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
892 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
893 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
894 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
895 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
897 chan
= &deviceExtension
->chan
[c
];
899 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, /*0x80*/ sizeof(IDE_REGISTERS_1
) + sizeof(IDE_REGISTERS_2
)*2);
901 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
902 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
904 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2;
905 UniataInitSyncBaseIO(chan
);
907 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
908 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
913 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
914 chan
= &deviceExtension
->chan
[c
];
915 if((ChipFlags
& VIABAR
) && (c
==2)) {
916 // Do not setup SATA registers for PATA part
917 for (i
=0; i
<=IDX_SATA_IO_SZ
; i
++) {
918 chan
->RegTranslation
[IDX_SATA_IO
+i
].Addr
= 0;
919 chan
->RegTranslation
[IDX_SATA_IO
+i
].MemIo
= 0;
923 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
924 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
925 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
926 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
927 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
928 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
930 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
939 if(!(ChipFlags
& UNIATA_SATA
)) {
943 /* the intel 31244 needs special care if in DPA mode */
944 if(DeviceID
== 3200 && // Intel 31244
945 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
947 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
948 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
950 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
951 KdPrint2((PRINT_PREFIX
"MemIo\n"));
954 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
955 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
956 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
958 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
959 ULONG offs
= 0x200 + c
*0x200;
961 chan
= &deviceExtension
->chan
[c
];
962 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
963 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
964 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
967 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
968 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
969 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
970 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
971 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
972 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
973 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
974 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
976 UniataInitSyncBaseIO(chan
);
978 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
979 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
980 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
982 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
983 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
985 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
986 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
987 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
988 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
989 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
990 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
992 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
993 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
994 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
995 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
996 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
997 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
999 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1004 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
1005 GetPciConfig1(0x90, tmp8
);
1006 KdPrint2((PRINT_PREFIX
"Intel chip config: %x\n", tmp8
));
1007 /* SATA parts can be either compat or AHCI */
1008 if(ChipFlags
& UNIATA_AHCI
) {
1011 //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
1013 KdPrint2((PRINT_PREFIX
"try run AHCI\n"));
1016 KdPrint2((PRINT_PREFIX
"Compatible mode\n"));
1018 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
1020 /* if BAR(5) is IO it should point to SATA interface registers */
1021 if(deviceExtension
->DevID
== 0x28288086 &&
1022 pciData
->u
.type0
.SubVendorID
== 0x106b) {
1024 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on ICH8M Apples\n"));
1026 /* Skip BAR(5) on ICH8M Apples, system locks up on access. */
1027 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1029 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1030 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1034 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1035 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1037 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1038 chan
= &deviceExtension
->chan
[c
];
1040 if(ChipFlags
& ICH5
) {
1041 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1042 if ((tmp8
& 0x04) == 0) {
1043 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1044 } else if ((tmp8
& 0x02) == 0) {
1047 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1049 } else if ((tmp8
& 0x02) != 0) {
1052 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1056 if(ChipFlags
& I6CH2
) {
1057 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1058 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1060 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1061 switch(tmp8
& 0x03) {
1078 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1079 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1082 if(/*(ChipFlags & ICH5) &&*/ BaseMemAddress
) {
1083 KdPrint2((PRINT_PREFIX
"BaseMemAddress[5] -> indexed\n"));
1084 chan
->RegTranslation
[IDX_INDEXED_ADDR
].Addr
= BaseMemAddress
+ 0;
1085 chan
->RegTranslation
[IDX_INDEXED_ADDR
].MemIo
= MemIo
;
1086 chan
->RegTranslation
[IDX_INDEXED_DATA
].Addr
= BaseMemAddress
+ 4;
1087 chan
->RegTranslation
[IDX_INDEXED_DATA
].MemIo
= MemIo
;
1089 if((ChipFlags
& ICH5
) || BaseMemAddress
) {
1091 KdPrint2((PRINT_PREFIX
"io indexed\n"));
1092 // Rather interesting way of register access...
1093 ChipType
= INTEL_IDX
;
1094 deviceExtension
->HwFlags
&= ~CHIPTYPE_MASK
;
1095 deviceExtension
->HwFlags
|= ChipType
;
1097 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= 0x200*c
+ 0;
1098 chan
->RegTranslation
[IDX_SATA_SStatus
].Proc
= 1;
1099 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= 0x200*c
+ 2;
1100 chan
->RegTranslation
[IDX_SATA_SError
].Proc
= 1;
1101 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= 0x200*c
+ 1;
1102 chan
->RegTranslation
[IDX_SATA_SControl
].Proc
= 1;
1108 // rest of INIT staff is in AtapiChipInit()
1113 /* Cyrix 5530 ATA33 controller */
1114 if(deviceExtension
->DevID
== 0x01021078) {
1115 ConfigInfo
->AlignmentMask
= 0x0f;
1116 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
1119 case ATA_JMICRON_ID
:
1120 /* New JMicron PATA controllers */
1121 GetPciConfig1(0xdf, tmp8
);
1123 KdPrint((" Check JMicron AHCI\n"));
1124 if(Ata_is_ahci_dev(pciData
)) {
1125 ChipFlags
|= UNIATA_AHCI
;
1126 deviceExtension
->HwFlags
|= UNIATA_AHCI
;
1128 KdPrint((" JMicron PATA\n"));
1131 /* set controller configuration to a combined setup we support */
1132 SetPciConfig4(0x40, 0x80c0a131);
1133 SetPciConfig4(0x80, 0x01200000);
1134 //KdPrint((" JMicron Combined (not supported yet)\n"));
1135 //return STATUS_NOT_FOUND;
1140 return STATUS_SUCCESS
;
1142 } // end UniataChipDetect()
1146 Do some 'magic staff' for VIA SouthBridge
1147 This will prevent data losses
1151 AtapiViaSouthBridgeFixup(
1152 IN PVOID HwDeviceExtension
,
1153 IN BUS_DATA_TYPE BusDataType
,
1154 IN ULONG SystemIoBusNumber
,
1158 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1159 PCI_COMMON_CONFIG pciData
;
1165 PCI_SLOT_NUMBER slotData
;
1167 BOOLEAN found
= FALSE
;
1169 slotData
.u
.AsULONG
= slotNumber
;
1170 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1172 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1174 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1179 PCI_COMMON_HDR_LENGTH
);
1181 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1185 VendorID
= pciData
.VendorID
;
1186 DeviceID
= pciData
.DeviceID
;
1187 dev_id
= (VendorID
| (DeviceID
<< 16));
1189 if (dev_id
== 0x03051106 || /* VIA VT8363 */
1190 dev_id
== 0x03911106 || /* VIA VT8371 */
1191 dev_id
== 0x31021106 || /* VIA VT8662 */
1192 dev_id
== 0x31121106) { /* VIA VT8361 */
1195 GetPciConfig1(0x76, reg76
);
1197 if ((reg76
& 0xf0) != 0xd0) {
1198 SetPciConfig1(0x75, 0x80);
1199 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
1206 deviceExtension
->HwFlags
&= ~VIABUG
;
1208 } // end AtapiViaSouthBridgeFixup()
1211 Do some 'magic staff' for ROSB SouthBridge
1212 This will prevent data losses
1216 AtapiRosbSouthBridgeFixup(
1217 IN PVOID HwDeviceExtension
,
1218 IN BUS_DATA_TYPE BusDataType
,
1219 IN ULONG SystemIoBusNumber
,
1223 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1224 PCI_COMMON_CONFIG pciData
;
1230 PCI_SLOT_NUMBER slotData
;
1232 // BOOLEAN found = FALSE;
1234 /* locate the ISA part in the southbridge and enable UDMA33 */
1235 slotData
.u
.AsULONG
= slotNumber
;
1236 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1238 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1240 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1245 PCI_COMMON_HDR_LENGTH
);
1247 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1251 VendorID
= pciData
.VendorID
;
1252 DeviceID
= pciData
.DeviceID
;
1253 dev_id
= (VendorID
| (DeviceID
<< 16));
1255 if (dev_id
== ATA_ROSB4_ISA
) { /* */
1256 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1260 } // end AtapiRosbSouthBridgeFixup()
1263 Do some 'magic staff' for ROSB SouthBridge
1264 This will prevent data losses
1268 AtapiAliSouthBridgeFixup(
1269 IN PVOID HwDeviceExtension
,
1270 IN BUS_DATA_TYPE BusDataType
,
1271 IN ULONG SystemIoBusNumber
,
1272 IN ULONG slotNumber
,
1276 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1277 PCI_COMMON_CONFIG pciData
;
1283 PCI_SLOT_NUMBER slotData
;
1285 // BOOLEAN found = FALSE;
1287 /* workaround for datacorruption bug found on at least SUN Blade-100
1288 * find the ISA function on the southbridge and disable then enable
1289 * the ATA channel tristate buffer */
1290 slotData
.u
.AsULONG
= slotNumber
;
1291 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1293 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1295 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1300 PCI_COMMON_HDR_LENGTH
);
1302 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1306 VendorID
= pciData
.VendorID
;
1307 DeviceID
= pciData
.DeviceID
;
1308 dev_id
= (VendorID
| (DeviceID
<< 16));
1310 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1311 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1312 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1316 } // end AtapiRosbSouthBridgeFixup()
1321 IN PHW_DEVICE_EXTENSION deviceExtension
,
1322 IN ULONG channel
// physical channel number (0-1)
1325 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1326 ULONG slotNumber
= deviceExtension
->slotNumber
;
1327 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1329 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1331 UCHAR reg
, val
, res
;
1332 PCI_SLOT_NUMBER slotData
;
1334 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1336 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1337 reg
= channel
? 0x57 : 0x53;
1338 GetPciConfig1(reg
, val
);
1339 SetPciConfig1(reg
, val
| 0x80);
1343 GetPciConfig1(reg
, val
);
1344 SetPciConfig1(reg
, val
& 0xfe);
1346 GetPciConfig1(0x5a, res
);
1347 res
= res
& (channel
? 0x01 : 0x02);
1348 SetPciConfig1(reg
, val
);
1350 } // end hpt_cable80()
1356 IN PHW_DEVICE_EXTENSION deviceExtension
,
1357 IN ULONG channel
// physical channel number (0-1)
1360 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1361 ULONG slotNumber
= deviceExtension
->slotNumber
;
1362 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1364 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1371 GetPciConfig1(0x50, reg50
);
1388 for (j
=0; j
>=2; i
-= 8) {
1389 i
= (3-(channel
*2+j
))*8;
1390 if (((reg50
>> (i
& 0x10)) & 8) &&
1391 ((reg50
>> i
) & 0x20) &&
1392 (((reg50
>> i
) & 7) < a
)) {
1394 res
|= TRUE
; //(1 << (1 - (i >> 4)));
1399 } // end via_cable80()
1404 IN PHW_DEVICE_EXTENSION deviceExtension
,
1405 IN ULONG channel
, // physical channel number (0-1)
1410 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1411 ULONG slotNumber
= deviceExtension
->slotNumber
;
1412 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1414 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1416 ULONG c
; // logical channel (for Compatible Mode controllers)
1419 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1420 chan
= &deviceExtension
->chan
[c
];
1422 GetPciConfig1(pci_reg
, tmp8
);
1423 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1424 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1429 } // end generic_cable80()
1433 UniAtaReadLunConfig(
1434 IN PHW_DEVICE_EXTENSION deviceExtension
,
1435 IN ULONG channel
, // physical channel
1436 IN ULONG DeviceNumber
1441 PHW_LU_EXTENSION LunExt
;
1444 c
= channel
- deviceExtension
->Channel
; // logical channel
1446 chan
= &deviceExtension
->chan
[c
];
1447 DeviceNumber
= (DeviceNumber
% deviceExtension
->NumberLuns
);
1448 LunExt
= chan
->lun
[DeviceNumber
];
1450 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadCacheEnable", 1);
1451 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1453 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"WriteCacheEnable", 1);
1454 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1456 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1457 LunExt
->opt_MaxTransferMode
= tmp32
;
1459 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"PreferedTransferMode", 0xffffffff);
1460 LunExt
->opt_PreferedTransferMode
= tmp32
;
1462 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadOnly", 0);
1464 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1467 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"GeomType", 0xffffffff);
1471 LunExt
->opt_GeomType
= tmp32
;
1473 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"Hidden", 0);
1475 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1479 } // end UniAtaReadLunConfig()
1483 AtapiReadChipConfig(
1484 IN PVOID HwDeviceExtension
,
1485 IN ULONG DeviceNumber
,
1486 IN ULONG channel
// physical channel
1489 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1492 ULONG c
; // logical channel (for Compatible Mode controllers)
1495 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1496 ASSERT(deviceExtension
);
1498 if(channel
!= CHAN_NOT_SPECIFIED
) {
1499 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1501 c
= CHAN_NOT_SPECIFIED
;
1504 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1506 if(channel
== CHAN_NOT_SPECIFIED
) {
1507 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1508 deviceExtension
->simplexOnly
= TRUE
;
1510 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1511 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1512 deviceExtension
->opt_AtapiDmaRawRead
= g_opt_AtapiDmaRawRead
;
1513 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1516 if(c
== CHAN_NOT_SPECIFIED
) {
1517 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1518 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1519 chan
= &deviceExtension
->chan
[c
];
1520 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1521 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1522 if(tmp32
!= 0xffffffff) {
1523 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1524 chan
->MaxTransferMode
= tmp32
;
1526 //UniAtaReadLunConfig(deviceExtension, c, 0);
1527 //UniAtaReadLunConfig(deviceExtension, c, 1);
1530 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1531 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1534 deviceExtension
->opt_AtapiDmaControlCmd
=
1535 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1538 deviceExtension
->opt_AtapiDmaRawRead
=
1539 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1542 deviceExtension
->opt_AtapiDmaReadWrite
=
1543 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1547 chan
= &deviceExtension
->chan
[c
];
1548 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1549 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1550 if(tmp32
!= 0xffffffff) {
1551 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1552 chan
->MaxTransferMode
= tmp32
;
1554 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1555 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1557 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1558 UniAtaReadLunConfig(deviceExtension
, channel
, i
);
1563 } // end AtapiReadChipConfig()
1568 IN PVOID HwDeviceExtension
,
1569 IN ULONG DeviceNumber
,
1570 IN ULONG channel
// physical channel
1573 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1574 ULONG slotNumber
= deviceExtension
->slotNumber
;
1575 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1576 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1577 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1578 ULONG RevID
= deviceExtension
->RevID
;
1580 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1581 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1582 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1587 ULONG c
; // logical channel (for Compatible Mode controllers)
1588 BOOLEAN CheckCable
= FALSE
;
1589 //ULONG BaseIoAddress;
1592 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1595 case CHAN_NOT_SPECIFIED
:
1596 c
= CHAN_NOT_SPECIFIED
;
1599 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1602 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1604 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1605 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1607 if(deviceExtension
->UnknownDev
) {
1608 KdPrint2((PRINT_PREFIX
" Unknown chip\n" ));
1610 VendorID
= 0xffffffff;
1614 if(ChipFlags
& UNIATA_AHCI
) {
1615 /* if BAR(5) is IO it should point to SATA interface registers */
1616 if(!deviceExtension
->BaseIoAHCI_0
.Addr
) {
1617 KdPrint2((PRINT_PREFIX
" !BaseIoAHCI_0, exiting\n" ));
1620 if(c
== CHAN_NOT_SPECIFIED
) {
1621 return UniataAhciInit(HwDeviceExtension
);
1623 if(c
<deviceExtension
->NumberChannels
) {
1624 KdPrint2((PRINT_PREFIX
" AHCI single channel init\n" ));
1625 UniataAhciReset(HwDeviceExtension
, c
);
1628 KdPrint2((PRINT_PREFIX
" AHCI non-existent channel\n" ));
1634 // case ATA_ACARD_ID:
1636 case ATA_ACER_LABS_ID
:
1637 if(ChipFlags
& UNIATA_SATA
) {
1638 if(c
== CHAN_NOT_SPECIFIED
) {
1639 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1640 chan
= &deviceExtension
->chan
[c
];
1641 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1642 /* the southbridge might need the data corruption fix */
1643 if(RevID
== 0xc2 || RevID
== 0xc3) {
1644 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1645 SystemIoBusNumber
, slotNumber
, c
);
1648 /* enable PCI interrupt */
1649 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1652 if(ChipFlags
& ALINEW
) {
1653 if(c
== CHAN_NOT_SPECIFIED
) {
1654 /* use device interrupt as byte count end */
1655 ChangePciConfig1(0x4a, (a
| 0x20));
1656 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
1658 ChangePciConfig1(0x4b, (a
| 0x09));
1661 /* enable ATAPI UDMA mode */
1662 ChangePciConfig1(0x53, (a
| (RevID
>= 0xc7 ? 0x03 : 0x01)));
1665 // check 80-pin cable
1666 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
1669 if(c
== CHAN_NOT_SPECIFIED
) {
1670 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1671 ChangePciConfig1(0x53, (a
| 0x03));
1674 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1679 if(c
== CHAN_NOT_SPECIFIED
) {
1680 /* set prefetch, postwrite */
1681 if(ChipFlags
& AMDBUG
) {
1682 ChangePciConfig1(0x41, (a
& 0x0f));
1684 ChangePciConfig1(0x41, (a
| 0xf0));
1687 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1689 // check 80-pin cable
1690 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
1691 if(c
== CHAN_NOT_SPECIFIED
) {
1694 generic_cable80(deviceExtension
, channel
, 0x42, 0);
1698 case ATA_HIGHPOINT_ID
:
1700 if(c
== CHAN_NOT_SPECIFIED
) {
1702 if(ChipFlags
& HPTOLD
) {
1703 /* turn off interrupt prediction */
1704 ChangePciConfig1(0x51, (a
& ~0x80));
1706 /* turn off interrupt prediction */
1707 ChangePciConfig1(0x51, (a
& ~0x03));
1708 ChangePciConfig1(0x55, (a
& ~0x03));
1709 /* turn on interrupts */
1710 ChangePciConfig1(0x5a, (a
& ~0x10));
1711 /* set clocks etc */
1712 if(ChipType
< HPT372
) {
1713 SetPciConfig1(0x5b, 0x22);
1715 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
1720 // check 80-pin cable
1721 chan
= &deviceExtension
->chan
[c
];
1722 if(!hpt_cable80(deviceExtension
, channel
)) {
1723 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1727 case ATA_INTEL_ID
: {
1731 if(ChipFlags
& UNIATA_SATA
) {
1733 KdPrint2((PRINT_PREFIX
"Intel SATA\n"));
1734 if(ChipFlags
& UNIATA_AHCI
) {
1735 KdPrint2((PRINT_PREFIX
"Do nothing for AHCI\n"));
1738 if(c
== CHAN_NOT_SPECIFIED
) {
1739 KdPrint2((PRINT_PREFIX
"Base init\n"));
1740 /* force all ports active "the legacy way" */
1741 ChangePciConfig2(0x92, (a
| 0x0f));
1742 /* enable PCI interrupt */
1743 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1747 KdPrint2((PRINT_PREFIX
"channel init\n"));
1749 GetPciConfig1(0x90, tmp8
);
1750 KdPrint2((PRINT_PREFIX
"reg 90: %x, init lun map\n", tmp8
));
1752 KdPrint2((PRINT_PREFIX
"chan %d\n", c
));
1753 chan
= &deviceExtension
->chan
[c
];
1755 if(ChipFlags
& ICH5
) {
1756 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1757 if ((tmp8
& 0x04) == 0) {
1758 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1759 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ^ c
;
1760 chan
->lun
[1]->SATA_lun_map
= 0;
1761 } else if ((tmp8
& 0x02) == 0) {
1763 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
1764 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
1767 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1769 } else if ((tmp8
& 0x02) != 0) {
1771 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
1772 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
1775 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1779 if(ChipFlags
& I6CH2
) {
1780 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1781 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1782 chan
->lun
[0]->SATA_lun_map
= c
? 0 : 1;
1783 chan
->lun
[1]->SATA_lun_map
= 0;
1785 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1786 switch(tmp8
& 0x03) {
1788 chan
->lun
[0]->SATA_lun_map
= 0+c
;
1789 chan
->lun
[1]->SATA_lun_map
= 2+c
;
1793 chan
->lun
[0]->SATA_lun_map
= 0;
1794 chan
->lun
[1]->SATA_lun_map
= 2;
1802 chan
->lun
[0]->SATA_lun_map
= 1;
1803 chan
->lun
[1]->SATA_lun_map
= 3;
1813 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1814 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1817 if(ChipType
== INTEL_IDX
) {
1818 KdPrint2((PRINT_PREFIX
"io indexed\n"));
1819 //for(c=0; c<deviceExtension->NumberChannels; c++) {
1820 chan
= &deviceExtension
->chan
[c
];
1821 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
1822 if(!(chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
)) {
1823 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 1);
1831 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1833 // check 80-pin cable
1834 if(c
== CHAN_NOT_SPECIFIED
) {
1837 chan
= &deviceExtension
->chan
[c
];
1838 GetPciConfig2(0x54, reg54
);
1839 if( ((reg54
>> (channel
*2)) & 30) != 30) {
1840 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1844 case ATA_NVIDIA_ID
: {
1845 if(ChipFlags
& UNIATA_SATA
) {
1846 if(c
== CHAN_NOT_SPECIFIED
) {
1847 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
1848 /* enable control access */
1849 ChangePciConfig1(0x50, (a
| 0x04));
1850 /* MCP55 seems to need some time to allow r_res2 read. */
1851 AtapiStallExecution(10);
1852 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
1853 if(ChipFlags
& NVQ
) {
1854 /* clear interrupt status */
1855 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
1856 /* enable device and PHY state change interrupts */
1857 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
1858 /* disable NCQ support */
1859 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
1860 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
1862 /* clear interrupt status */
1863 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
1864 /* enable device and PHY state change interrupts */
1865 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
1867 /* enable PCI interrupt */
1868 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1870 //UniataSataPhyEnable(HwDeviceExtension, c);
1875 if(c
== CHAN_NOT_SPECIFIED
) {
1876 /* set prefetch, postwrite */
1877 ChangePciConfig1(0x51, (a
& 0x0f));
1879 // check 80-pin cable
1880 generic_cable80(deviceExtension
, channel
, 0x52, 1);
1881 /* chan = &deviceExtension->chan[c];
1882 GetPciConfig1(0x52, reg52);
1883 if( !((reg52 >> (channel*2)) & 0x01)) {
1884 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1889 case ATA_PROMISE_ID
: {
1894 if(c
== CHAN_NOT_SPECIFIED
) {
1895 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
1896 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
1897 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
1901 /* enable burst mode */
1902 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
1903 if(c
== CHAN_NOT_SPECIFIED
) {
1904 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
1905 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
1907 // check 80-pin cable
1908 chan
= &deviceExtension
->chan
[c
];
1909 GetPciConfig2(0x50, Reg50
);
1910 if(Reg50
& (1 << (channel
+10))) {
1911 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1916 if(c
== CHAN_NOT_SPECIFIED
) {
1919 // check 80-pin cable
1920 chan
= &deviceExtension
->chan
[c
];
1921 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
1922 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
1923 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1928 if(c
== CHAN_NOT_SPECIFIED
) {
1929 if(ChipFlags
& PRSATA
) {
1930 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x6c, 0x000000ff);
1933 chan
= &deviceExtension
->chan
[c
];
1934 AtapiWritePort4(chan
, IDX_BM_Command
,
1935 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
1936 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
1937 // check 80-pin cable
1938 if(chan
->MaxTransferMode
< ATA_SA150
&&
1939 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
1940 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1946 case ATA_SERVERWORKS_ID
:
1947 if(c
== CHAN_NOT_SPECIFIED
) {
1948 if(ChipType
== SWKS33
) {
1949 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1950 SystemIoBusNumber
, slotNumber
);
1952 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
1957 if(ChipType
== SIIMIO
) {
1958 KdPrint2((PRINT_PREFIX
"ATI New\n"));
1961 KdPrint2((PRINT_PREFIX
"ATI\n"));
1964 case ATA_SILICON_IMAGE_ID
:
1965 /* if(ChipFlags & SIIENINTR) {
1966 SetPciConfig1(0x71, 0x01);
1971 KdPrint2((PRINT_PREFIX
"SII\n"));
1974 if(c
== CHAN_NOT_SPECIFIED
) {
1975 if(ChipFlags
& SIISETCLK
) {
1976 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
1977 GetPciConfig1(0x8a, tmp8
);
1978 if ((tmp8
& 0x30) != 0x10)
1979 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
1980 GetPciConfig1(0x8a, tmp8
);
1981 if ((tmp8
& 0x30) != 0x10) {
1982 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
1983 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1987 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
1988 // check 80-pin cable
1989 if(c
== CHAN_NOT_SPECIFIED
) {
1992 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
1993 chan
= &deviceExtension
->chan
[c
];
1994 GetPciConfig2(0x79, Reg79
);
1995 if(Reg79
& (channel
? 0x02 : 0x01)) {
1996 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2000 ULONG unit01
= (c
& 1);
2001 ULONG unit10
= (c
& 2);
2002 /* enable/disable PHY state change interrupt */
2003 if(c
== CHAN_NOT_SPECIFIED
) {
2004 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2007 if(ChipFlags
& SIINOSATAIRQ
) {
2008 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2009 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2013 if(ChipFlags
& SIINOSATAIRQ
) {
2014 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2015 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2017 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
2018 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
2022 if(c
== CHAN_NOT_SPECIFIED
) {
2023 /* enable interrupt as BIOS might not */
2024 ChangePciConfig1(0x8a, (a
& 0x3f));
2025 // Enable 3rd and 4th channels
2026 if (ChipFlags
& SII4CH
) {
2027 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
2028 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
2031 chan
= &deviceExtension
->chan
[c
];
2032 /* dont block interrupts */
2033 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2034 tmp32
= AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2035 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
2037 tmp32
= AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2039 /* Initialize FIFO PCI bus arbitration */
2040 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
2042 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp32
));
2044 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
2046 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
2053 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
2054 if(c
== CHAN_NOT_SPECIFIED
) {
2055 /* Setup interrupts. */
2056 SetPciConfig1(0x71, 0x01);
2058 /* GetPciConfig1(0x8a, tmp8);
2060 SetPciConfig1(0x71, tmp8);*/
2062 /* Use MEMORY READ LINE for reads.
2063 * NOTE: Although not mentioned in the PCI0646U specs,
2064 * these bits are write only and won't be read
2065 * back as set or not. The PCI0646U2 specs clarify
2069 SetPciConfig1(0x71, tmp8);
2071 /* Set reasonable active/recovery/address-setup values. */
2072 SetPciConfig1(0x53, 0x40);
2073 SetPciConfig1(0x54, 0x3f);
2074 SetPciConfig1(0x55, 0x40);
2075 SetPciConfig1(0x56, 0x3f);
2076 SetPciConfig1(0x57, 0x1c);
2077 SetPciConfig1(0x58, 0x3f);
2078 SetPciConfig1(0x5b, 0x3f);
2085 if(c
== CHAN_NOT_SPECIFIED
) {
2091 ChangePciConfig1(0x52, (a
& ~0x04));
2095 ChangePciConfig1(0x49, (a
& ~0x01));
2098 ChangePciConfig2(0x50, (a
| 0x0008));
2099 ChangePciConfig2(0x52, (a
| 0x0008));
2102 ChangePciConfig2(0x04, (a
& ~0x0400));
2105 if(ChipType
== SIS133NEW
) {
2107 // check 80-pin cable
2108 if(c
== CHAN_NOT_SPECIFIED
) {
2111 chan
= &deviceExtension
->chan
[c
];
2112 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
2113 if(tmp16
& 0x8000) {
2114 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2118 // check 80-pin cable
2119 if(c
== CHAN_NOT_SPECIFIED
) {
2122 chan
= &deviceExtension
->chan
[c
];
2123 GetPciConfig1(48, tmp8
);
2124 if(tmp8
& (0x10 << channel
)) {
2125 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2132 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2135 if(c
== CHAN_NOT_SPECIFIED
) {
2136 /* prepare for ATA-66 on the 82C686a and 82C596b */
2137 if(ChipFlags
& VIACLK
) {
2138 ChangePciConfig4(0x50, (a
| 0x030b030b));
2141 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2142 /* enable PCI interrupt */
2143 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
2146 * vt6420/1 has problems talking to some drives. The following
2147 * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
2149 * When host issues HOLD, device may send up to 20DW of data
2150 * before acknowledging it with HOLDA and the host should be
2151 * able to buffer them in FIFO. Unfortunately, some WD drives
2152 * send upto 40DW before acknowledging HOLD and, in the
2153 * default configuration, this ends up overflowing vt6421's
2154 * FIFO, making the controller abort the transaction with
2157 * Rx52[2] is the internal 128DW FIFO Flow control watermark
2158 * adjusting mechanism enable bit and the default value 0
2159 * means host will issue HOLD to device when the left FIFO
2160 * size goes below 32DW. Setting it to 1 makes the watermark
2163 * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
2166 if(DeviceID
== 0x3149 || DeviceID
== 0x3249) { //vt6420 or vt6421
2167 KdPrint2((PRINT_PREFIX
"VIA 642x FIFO\n"));
2168 ChangePciConfig1(0x52, a
| (1 << 2));
2174 /* the southbridge might need the data corruption fix */
2175 if(ChipFlags
& VIABUG
) {
2176 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2177 SystemIoBusNumber
, slotNumber
);
2179 /* set prefetch, postwrite */
2180 if(ChipType
!= VIA133
) {
2181 ChangePciConfig1(0x41, (a
| 0xf0));
2184 /* set fifo configuration half'n'half */
2185 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
2187 /* set status register read retry */
2188 ChangePciConfig1(0x44, (a
| 0x08));
2190 /* set DMA read & end-of-sector fifo flush */
2191 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
2193 /* set sector size */
2194 SetPciConfig2(0x60, DEV_BSIZE
);
2195 SetPciConfig2(0x68, DEV_BSIZE
);
2198 chan
= &deviceExtension
->chan
[c
];
2200 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2201 if((ChipFlags
& VIABAR
) && (c
>= 2)) {
2204 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2208 // check 80-pin cable
2209 if(!via_cable80(deviceExtension
, channel
)) {
2210 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2217 if(ChipType
== ITE_33
|| ChipType
== ITE_133_NEW
) {
2220 if(ChipType
== ITE_133
) {
2221 if(c
== CHAN_NOT_SPECIFIED
) {
2222 /* set PCI mode and 66Mhz reference clock */
2223 ChangePciConfig1(0x50, a
& ~0x83);
2225 /* set default active & recover timings */
2226 SetPciConfig1(0x54, 0x31);
2227 SetPciConfig1(0x56, 0x31);
2229 // check 80-pin cable
2230 GetPciConfig2(0x40, tmp16
);
2231 chan
= &deviceExtension
->chan
[c
];
2232 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
2233 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2237 if(ChipType
== ITE_133_NEW
) {
2241 if(c
!= CHAN_NOT_SPECIFIED
) {
2242 // We don't know how to check for 80-pin cable on unknown controllers.
2243 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2244 // So, leave this flag to use as hint in error recovery procedures
2245 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
2246 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
2251 // In all places separate channels are inited after common controller init
2252 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2253 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
2254 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2255 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
2260 } // end AtapiChipInit()
2265 IN PHW_DEVICE_EXTENSION deviceExtension
,
2266 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
2274 if(!BaseIoAddressBM_0
) {
2277 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2278 chan
= &deviceExtension
->chan
[c
];
2279 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
2280 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONGIO_PTR
)BaseIoAddressBM_0
+ i
) : 0;
2281 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
2283 if(BaseIoAddressBM_0
) {
2284 BaseIoAddressBM_0
++;
2287 } // end UniataInitMapBM()
2292 IN PHW_CHANNEL chan
,
2293 IN PIDE_REGISTERS_1 BaseIoAddress1
,
2294 IN PIDE_REGISTERS_2 BaseIoAddress2
2299 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
2300 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONGIO_PTR
)BaseIoAddress1
+ i
) : 0;
2301 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
2303 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
2304 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONGIO_PTR
)BaseIoAddress2
+ i
) : 0;
2305 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
2307 UniataInitSyncBaseIO(chan
);
2308 } // end UniataInitMapBase()
2312 UniataInitSyncBaseIO(
2316 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
2317 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
2318 } // end UniataInitSyncBaseIO()
2323 IN PHW_CHANNEL chan
,
2324 IN PHW_DEVICE_EXTENSION deviceExtension
,
2330 if(!deviceExtension
->NumberLuns
) {
2331 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
;
2333 chan
->DeviceExtension
= deviceExtension
;
2335 chan
->NumberLuns
= deviceExtension
->NumberLuns
;
2336 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2337 chan
->lun
[i
] = &(deviceExtension
->lun
[c
*deviceExtension
->NumberLuns
+i
]);
2339 chan
->AltRegMap
= deviceExtension
->AltRegMap
;
2340 chan
->NextDpcChan
= -1;
2341 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2342 chan
->lun
[i
]->DeviceExtension
= deviceExtension
;
2343 chan
->lun
[i
]->chan
= chan
;
2344 chan
->lun
[i
]->Lun
= i
;
2346 } // end AtapiSetupLunPtrs()