3 Copyright (c) 2004-2007 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 IN PVOID HwDeviceExtension
,
49 IN PPCI_COMMON_CONFIG pciData
, // optional
50 IN ULONG DeviceNumber
,
51 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
52 IN BOOLEAN
* simplexOnly
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
;
62 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
71 ULONG BaseIoAddressBM
;
72 BOOLEAN MemIo
= FALSE
;
74 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
75 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
77 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
79 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
84 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
85 if(i
!= BMLIST_TERMINATOR
) {
86 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
89 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
.Addr
? ATA_DMA
: ATA_PIO4
;
93 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
94 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
95 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
96 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
97 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
98 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
99 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
100 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
102 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
103 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
104 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
105 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
107 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
108 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),
109 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
110 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
111 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
112 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
113 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
114 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
116 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
117 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
118 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
120 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
121 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
123 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
124 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
125 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
126 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
127 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
128 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
131 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
132 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
133 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
134 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
135 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
136 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
137 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
138 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
139 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
140 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
141 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
142 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
143 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
144 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| VIAAST
),
145 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| VIAAST
),
146 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| VIAAST
),
147 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| VIAAST
),
148 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
151 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
152 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH
),
153 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH
),
154 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH
),
155 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH
),
156 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
159 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
164 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
165 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
166 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, -1, NULL
);
170 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
171 // New chips have own DeviceId
172 if(deviceExtension
->DevID
!= ATA_VIA82C571
)
174 // Old chips have same DeviceId, we can distinguish between them
175 // only by SouthBridge DeviceId
176 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
177 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, slotNumber
, NULL
);
179 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
180 deviceExtension
->HwFlags
|= VIASOUTH
;
182 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
183 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, slotNumber
, NULL
);
192 KdPrint2((PRINT_PREFIX
"Default\n"));
194 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
195 /* do extra chipset specific setups */
196 switch(deviceExtension
->DevID
) {
198 //case ATA_CYPRESS_ID:
199 case 0xc6931080: /* 82c693 ATA controller */
200 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
203 case 0x000116ca: /* Cenatek Rocket Drive controller */
204 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
207 /* case ATA_CYRIX_ID:
208 DevTypeInfo = &CyrixAdapters[0];
210 case 0x01021078: /* Cyrix 5530 ATA33 controller */
211 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
214 case 0x06401095: /* CMD 640 known bad, no DMA */
220 case 0x10001042: /* RZ 100? known bad, no DMA */
223 if(deviceExtension
->BaseIoAddressBM_0
)
224 ScsiPortFreeDeviceBase(HwDeviceExtension
,
225 deviceExtension
->BaseIoAddressBM_0
);
227 deviceExtension
->BaseIoAddressBM_0
= 0;
228 deviceExtension
->BusMaster
= FALSE
;
229 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
232 case 0x81721283: /* IT8172 IDE controller */
233 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
244 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
246 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
250 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
251 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
253 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
255 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
256 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
257 deviceExtension
->HwFlags
= tmp32
;
259 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
260 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
261 deviceExtension
->HwFlags
|= tmp32
;
263 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
264 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
265 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
269 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
270 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
271 if(tmp32
!= 0xffffffff) {
272 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
273 deviceExtension
->MaxTransferMode
= tmp32
;
276 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
277 deviceExtension
->HwFlags
|= UNIATA_SATA
;
280 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
281 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
283 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
284 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
287 case ATA_ACER_LABS_ID
:
288 switch(deviceExtension
->DevID
) {
291 deviceExtension
->NumberChannels
= 4;
293 if(ChipFlags
& UNIATA_SATA
) {
294 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
295 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
297 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
299 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
300 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
301 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
302 ULONG unit01
= (c
& 1);
303 ULONG unit10
= (c
& 2);
304 chan
= &deviceExtension
->chan
[c
];
306 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
307 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
309 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
310 UniataInitSyncBaseIO(chan
);
312 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
313 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
316 // SATA not supported yet
318 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
319 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
320 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
322 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
327 if(ChipFlags
& UNIATA_SATA
) {
328 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
329 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
330 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
331 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
332 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
333 KdPrint2((PRINT_PREFIX
"MemIo\n"));
336 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
337 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
338 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
339 chan
= &deviceExtension
->chan
[c
];
341 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
342 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
343 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
344 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
345 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
346 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
348 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
354 if(ChipType
!= PRMIO
) {
357 deviceExtension
->NumberChannels
= 4;
361 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
362 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
364 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
365 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
366 KdPrint2((PRINT_PREFIX
"MemIo\n"));
369 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
370 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
371 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
375 chan
= &deviceExtension
->chan
[c
];
380 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
381 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs12
;
382 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
384 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
385 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
387 UniataInitSyncBaseIO(chan
);
389 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
390 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
391 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
392 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
393 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
394 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
399 KdPrint2((PRINT_PREFIX
"ATI\n"));
400 case ATA_SILICON_IMAGE_ID
: {
402 if(ChipFlags
& SIIBUG
) {
404 if(ChipType
!= SIIMIO
) {
411 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
412 KdPrint2((PRINT_PREFIX
"New SII\n"));
414 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
416 //if(deviceExtension->HwFlags & SII4CH) {
417 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
419 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
421 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
422 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
423 KdPrint2((PRINT_PREFIX
"MemIo\n"));
426 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
427 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
428 if(deviceExtension
->HwFlags
& SII4CH
) {
429 deviceExtension
->NumberChannels
= 4;
432 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
433 ULONG unit01
= (c
& 1);
434 ULONG unit10
= (c
& 2);
436 chan
= &deviceExtension
->chan
[c
];
438 if(deviceExtension
->AltRegMap
) {
439 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
440 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
441 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
443 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
444 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
445 UniataInitSyncBaseIO(chan
);
447 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
448 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
449 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
450 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
451 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
452 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
453 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
454 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
455 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
456 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
457 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
458 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
461 if(ChipFlags
& UNIATA_SATA
) {
462 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
463 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
464 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
465 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
466 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
467 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
469 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
474 case ATA_SERVERWORKS_ID
: {
476 if(ChipType
!= SWKSMIO
) {
483 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
485 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
486 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
488 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
489 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
490 KdPrint2((PRINT_PREFIX
"MemIo\n"));
493 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
494 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
496 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
497 ULONG offs
= c
*0x100;
499 chan
= &deviceExtension
->chan
[c
];
500 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
501 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
502 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
504 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
505 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
506 UniataInitSyncBaseIO(chan
);
508 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
509 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
510 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
511 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
512 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
513 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
515 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
516 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
517 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
518 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
519 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
520 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
522 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
527 //if(ChipType != SIS_SOUTH) {
528 BOOLEAN SIS_182
=FALSE
;
530 if(!(ChipFlags
& SIS_BASE
)) {
531 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
532 //PrintNtConsole("Found SIS_SOUTH\n");
535 // Make some additional checks
536 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
537 ChangePciConfig1(0x57, (a
& 0x7f));
538 GetPciConfig4(0x00, tmp32
);
539 if(tmp32
== ATA_SIS5518
) {
540 ChipType
= SIS133NEW
;
541 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
542 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
543 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
544 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
546 ChangePciConfig1(0x57, (a
| 0x80));
548 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
549 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
550 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
551 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, -1, NULL
, -1 )
554 GetPciConfig1(0x4a, tmp8
);
555 ChangePciConfig1(0x4a, (a
| 0x10));
556 if(tmp32
== ATA_SIS5513
||
557 tmp32
== ATA_SIS5517
) {
558 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
559 -1, HwDeviceExtension
, SystemIoBusNumber
, -1, NULL
);
561 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
562 //deviceExtension->MaxTransferMode = ATA_UDMA6;
563 deviceExtension
->MaxTransferMode
= SiSSouthAdapters
[i
].MaxTransferMode
;
564 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
565 deviceExtension
->HwFlags
|= UNIATA_SATA
;
566 if(SiSSouthAdapters
[i
].nDeviceId
== 0x01182) {
571 // SiS-South not found
572 if(tmp32
== ATA_SIS5517
) {
573 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
574 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
577 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
582 SetPciConfig1(0x4a, tmp8
);
583 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
584 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
585 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
586 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
588 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
590 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
591 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
592 KdPrint2((PRINT_PREFIX
"MemIo\n"));
595 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
596 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
598 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
599 ULONG offs
= c
<< (SIS_182
? 5 : 6);
601 chan
= &deviceExtension
->chan
[c
];
602 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
603 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
604 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
605 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
606 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
607 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
609 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
613 //ChangePciConfig1(0x57, (a | 0x80));
618 if(ChipFlags
& UNIATA_SATA
) {
623 case 3149: // VIA 6420
626 case 3249: // VIA 6421
631 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
632 5, 0, IoSize
* deviceExtension
->NumberChannels
);
633 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
634 KdPrint2((PRINT_PREFIX
"MemIo\n"));
637 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
638 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
640 if(/*deviceExtension->*/BaseMemAddress
) {
641 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
642 if(ChipFlags
& VIABAR
) {
644 ULONG BaseIoAddressBM_0
;
647 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
648 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
649 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
650 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
651 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
652 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
654 chan
= &deviceExtension
->chan
[c
];
656 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, 0x80);
658 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
659 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
661 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2 + FIELD_OFFSET(IDE_REGISTERS_2
, AltStatus
);
662 UniataInitSyncBaseIO(chan
);
664 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
665 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
667 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
668 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
669 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
670 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
671 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
672 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
674 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
682 if(!(ChipFlags
& UNIATA_SATA
)) {
686 /* the intel 31244 needs special care if in DPA mode */
687 if(DeviceID
== 3200 && // Intel 31244
688 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
690 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
691 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
693 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
694 KdPrint2((PRINT_PREFIX
"MemIo\n"));
697 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
698 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
699 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
701 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
702 ULONG offs
= 0x200 + c
*0x200;
704 chan
= &deviceExtension
->chan
[c
];
705 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
706 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
707 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
710 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
711 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
712 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
713 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
714 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
715 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
716 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
717 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
719 UniataInitSyncBaseIO(chan
);
721 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
722 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
723 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
725 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
726 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
728 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
729 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
730 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
731 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
732 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
733 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
735 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
736 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
737 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
738 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
739 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
740 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
742 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
747 /* SATA parts can be either compat or AHCI */
748 if(ChipFlags
& UNIATA_AHCI
) {
750 GetPciConfig1(0x90, tmp8
);
752 KdPrint2((PRINT_PREFIX
"AHCI not supported yet\n"));
755 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
758 if(ChipFlags
& UNIATA_SATA
) {
759 //BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
761 BaseMemAddress
= NULL
; // HACK-HACK
762 if(!BaseMemAddress
) {
763 KdPrint2((PRINT_PREFIX
"Intel: no SATA I/O space, operate in PATA Compatible mode\n"));
764 deviceExtension
->HwFlags
&= ~UNIATA_SATA
;
767 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
768 KdPrint2((PRINT_PREFIX
"MemIo\n"));
771 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
772 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
777 /* Cyrix 5530 ATA33 controller */
778 if(deviceExtension
->DevID
== 0x01021078) {
779 ConfigInfo
->AlignmentMask
= 0x0f;
780 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
787 } // end UniataChipDetect()
791 Do some 'magic staff' for VIA SouthBridge
792 This will prevent data losses
795 AtapiViaSouthBridgeFixup(
796 IN PVOID HwDeviceExtension
,
797 IN BUS_DATA_TYPE BusDataType
,
798 IN ULONG SystemIoBusNumber
,
802 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
803 PCI_COMMON_CONFIG pciData
;
809 PCI_SLOT_NUMBER slotData
;
811 BOOLEAN found
= FALSE
;
813 slotData
.u
.AsULONG
= slotNumber
;
814 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
816 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
818 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
823 PCI_COMMON_HDR_LENGTH
);
825 if (busDataRead
< PCI_COMMON_HDR_LENGTH
) {
829 VendorID
= pciData
.VendorID
;
830 DeviceID
= pciData
.DeviceID
;
831 dev_id
= (VendorID
| (DeviceID
<< 16));
833 if (dev_id
== 0x03051106 || /* VIA VT8363 */
834 dev_id
== 0x03911106 || /* VIA VT8371 */
835 dev_id
== 0x31021106 || /* VIA VT8662 */
836 dev_id
== 0x31121106) { /* VIA VT8361 */
839 GetPciConfig1(0x76, reg76
);
841 if ((reg76
& 0xf0) != 0xd0) {
842 SetPciConfig1(0x75, 0x80);
843 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
850 deviceExtension
->HwFlags
&= ~VIABUG
;
852 } // end AtapiViaSouthBridgeFixup()
855 Do some 'magic staff' for ROSB SouthBridge
856 This will prevent data losses
859 AtapiRosbSouthBridgeFixup(
860 IN PVOID HwDeviceExtension
,
861 IN BUS_DATA_TYPE BusDataType
,
862 IN ULONG SystemIoBusNumber
,
866 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
867 PCI_COMMON_CONFIG pciData
;
873 PCI_SLOT_NUMBER slotData
;
875 // BOOLEAN found = FALSE;
877 /* locate the ISA part in the southbridge and enable UDMA33 */
878 slotData
.u
.AsULONG
= slotNumber
;
879 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
881 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
883 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
888 PCI_COMMON_HDR_LENGTH
);
890 if (busDataRead
< PCI_COMMON_HDR_LENGTH
) {
894 VendorID
= pciData
.VendorID
;
895 DeviceID
= pciData
.DeviceID
;
896 dev_id
= (VendorID
| (DeviceID
<< 16));
898 if (dev_id
== ATA_ROSB4_ISA
) { /* VIA VT8361 */
899 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
903 } // end AtapiRosbSouthBridgeFixup()
906 Do some 'magic staff' for ROSB SouthBridge
907 This will prevent data losses
910 AtapiAliSouthBridgeFixup(
911 IN PVOID HwDeviceExtension
,
912 IN BUS_DATA_TYPE BusDataType
,
913 IN ULONG SystemIoBusNumber
,
918 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
919 PCI_COMMON_CONFIG pciData
;
925 PCI_SLOT_NUMBER slotData
;
927 // BOOLEAN found = FALSE;
929 /* workaround for datacorruption bug found on at least SUN Blade-100
930 * find the ISA function on the southbridge and disable then enable
931 * the ATA channel tristate buffer */
932 slotData
.u
.AsULONG
= slotNumber
;
933 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
935 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
937 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
942 PCI_COMMON_HDR_LENGTH
);
944 if (busDataRead
< PCI_COMMON_HDR_LENGTH
) {
948 VendorID
= pciData
.VendorID
;
949 DeviceID
= pciData
.DeviceID
;
950 dev_id
= (VendorID
| (DeviceID
<< 16));
952 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
953 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
954 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
958 } // end AtapiRosbSouthBridgeFixup()
962 IN PHW_DEVICE_EXTENSION deviceExtension
,
963 IN ULONG channel
// physical channel number (0-1)
966 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
967 ULONG slotNumber
= deviceExtension
->slotNumber
;
968 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
970 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
973 PCI_SLOT_NUMBER slotData
;
975 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
977 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
978 reg
= channel
? 0x57 : 0x53;
979 GetPciConfig1(reg
, val
);
980 SetPciConfig1(reg
, val
| 0x80);
984 GetPciConfig1(reg
, val
);
985 SetPciConfig1(reg
, val
& 0xfe);
987 GetPciConfig1(0x5a, res
);
988 res
= res
& (channel
? 0x01 : 0x02);
989 SetPciConfig1(reg
, val
);
991 } // end hpt_cable80()
996 IN PHW_DEVICE_EXTENSION deviceExtension
,
997 IN ULONG channel
// physical channel number (0-1)
1000 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1001 ULONG slotNumber
= deviceExtension
->slotNumber
;
1002 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1004 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1011 GetPciConfig1(0x50, reg50
);
1028 for (j
=0; j
>=2; i
-= 8) {
1029 i
= (3-(channel
*2+j
))*8;
1030 if (((reg50
>> (i
& 16)) & 8) &&
1031 ((reg50
>> i
) & 0x20) &&
1032 (((reg50
>> i
) & 7) < a
)) {
1034 res
|= TRUE
; //(1 << (1 - (i >> 4)));
1039 } // end via_cable80()
1042 UniAtaReadLunConfig(
1043 IN PHW_DEVICE_EXTENSION deviceExtension
,
1044 IN ULONG channel
, // physical channel
1050 PHW_LU_EXTENSION LunExt
;
1053 c
= channel
- deviceExtension
->Channel
; // logical channel
1055 chan
= &deviceExtension
->chan
[c
];
1057 LunExt
= &(deviceExtension
->lun
[c
*2+ldev
]);
1059 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"ReadCacheEnable", 1);
1060 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1062 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"WriteCacheEnable", 1);
1063 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1065 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1066 LunExt
->opt_MaxTransferMode
= tmp32
;
1068 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"PreferedTransferMode", 0xffffffff);
1069 LunExt
->opt_PreferedTransferMode
= tmp32
;
1071 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"GeomType", 0xffffffff);
1075 LunExt
->opt_GeomType
= tmp32
;
1078 } // end UniAtaReadLunConfig()
1081 AtapiReadChipConfig(
1082 IN PVOID HwDeviceExtension
,
1083 IN ULONG DeviceNumber
,
1084 IN ULONG channel
// physical channel
1087 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1090 ULONG c
; // logical channel (for Compatible Mode controllers)
1092 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1093 ASSERT(deviceExtension
);
1095 if(channel
!= CHAN_NOT_SPECIFIED
) {
1096 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1098 c
= CHAN_NOT_SPECIFIED
;
1101 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1103 if(channel
== CHAN_NOT_SPECIFIED
) {
1104 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1105 deviceExtension
->simplexOnly
= TRUE
;
1107 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1108 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1109 deviceExtension
->opt_AtapiDmaRawRead
= TRUE
;
1110 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1113 if(c
== CHAN_NOT_SPECIFIED
) {
1114 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1115 chan
= &deviceExtension
->chan
[c
];
1116 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1117 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1118 if(tmp32
!= 0xffffffff) {
1119 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1120 chan
->MaxTransferMode
= tmp32
;
1122 //UniAtaReadLunConfig(deviceExtension, c, 0);
1123 //UniAtaReadLunConfig(deviceExtension, c, 1);
1126 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1127 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1130 deviceExtension
->opt_AtapiDmaControlCmd
=
1131 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1134 deviceExtension
->opt_AtapiDmaRawRead
=
1135 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1138 deviceExtension
->opt_AtapiDmaReadWrite
=
1139 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1143 chan
= &deviceExtension
->chan
[c
];
1144 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1145 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1146 if(tmp32
!= 0xffffffff) {
1147 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1148 chan
->MaxTransferMode
= tmp32
;
1150 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1151 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1153 UniAtaReadLunConfig(deviceExtension
, channel
, 0);
1154 UniAtaReadLunConfig(deviceExtension
, channel
, 1);
1158 } // end AtapiReadChipConfig()
1162 IN PVOID HwDeviceExtension
,
1163 IN ULONG DeviceNumber
,
1164 IN ULONG channel
// physical channel
1167 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1168 ULONG slotNumber
= deviceExtension
->slotNumber
;
1169 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1170 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1171 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1172 ULONG RevID
= deviceExtension
->RevID
;
1174 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1175 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1176 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1181 ULONG c
; // logical channel (for Compatible Mode controllers)
1182 //ULONG BaseIoAddress;
1184 if(channel
!= CHAN_NOT_SPECIFIED
) {
1185 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1187 c
= CHAN_NOT_SPECIFIED
;
1190 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1192 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1193 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1195 if(deviceExtension
->UnknownDev
) {
1196 KdPrint2((PRINT_PREFIX
" Unknown chip, exiting\n" ));
1198 VendorID
= 0xffffffff;
1202 // case ATA_ACARD_ID:
1204 case ATA_ACER_LABS_ID
:
1205 if(ChipFlags
& UNIATA_SATA
) {
1206 if(c
== CHAN_NOT_SPECIFIED
) {
1207 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1208 chan
= &deviceExtension
->chan
[c
];
1209 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1210 /* the southbridge might need the data corruption fix */
1211 if(RevID
== 0xc2 || RevID
== 0xc3) {
1212 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1213 SystemIoBusNumber
, slotNumber
, c
);
1216 /* enable PCI interrupt */
1217 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1220 if(ChipFlags
& ALINEW
) {
1221 if(c
== CHAN_NOT_SPECIFIED
) {
1222 /* use device interrupt as byte count end */
1223 ChangePciConfig1(0x4a, (a
| 0x20));
1224 /* enable cable detection and UDMA support on newer chips */
1225 ChangePciConfig1(0x4b, (a
| 0x09));
1227 /* enable ATAPI UDMA mode */
1228 ChangePciConfig1(0x53, (a
| 0x01));
1231 if(c
== CHAN_NOT_SPECIFIED
) {
1232 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1233 ChangePciConfig1(0x53, (a
| 0x03));
1235 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1236 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1240 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1245 if(c
== CHAN_NOT_SPECIFIED
) {
1246 /* set prefetch, postwrite */
1247 if(ChipFlags
& AMDBUG
) {
1248 ChangePciConfig1(0x41, (a
& 0x0f));
1250 ChangePciConfig1(0x41, (a
| 0xf0));
1253 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1255 // check 80-pin cable
1256 if(ChipFlags
& AMDCABLE
) {
1257 if(c
== CHAN_NOT_SPECIFIED
) {
1258 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1259 chan
= &deviceExtension
->chan
[c
];
1260 GetPciConfig1(0x42, tmp8
);
1261 if(!(tmp8
& (1 << channel
))) {
1262 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1266 chan
= &deviceExtension
->chan
[c
];
1267 GetPciConfig1(0x42, tmp8
);
1268 if(!(tmp8
& (1 << channel
))) {
1269 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1274 case ATA_HIGHPOINT_ID
:
1276 if(c
== CHAN_NOT_SPECIFIED
) {
1278 if(ChipFlags
& HPTOLD
) {
1279 /* turn off interrupt prediction */
1280 ChangePciConfig1(0x51, (a
& ~0x80));
1282 /* turn off interrupt prediction */
1283 ChangePciConfig1(0x51, (a
& ~0x03));
1284 ChangePciConfig1(0x55, (a
& ~0x03));
1285 /* turn on interrupts */
1286 ChangePciConfig1(0x5a, (a
& ~0x10));
1287 /* set clocks etc */
1288 if(ChipType
< HPT372
) {
1289 SetPciConfig1(0x5b, 0x22);
1291 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
1295 // check 80-pin cable
1296 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1297 chan
= &deviceExtension
->chan
[c
];
1298 if(!hpt_cable80(deviceExtension
, channel
)) {
1299 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1303 // check 80-pin cable
1304 chan
= &deviceExtension
->chan
[c
];
1305 if(!hpt_cable80(deviceExtension
, channel
)) {
1306 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1310 case ATA_INTEL_ID
: {
1312 if(ChipFlags
& UNIATA_SATA
) {
1313 if(c
!= CHAN_NOT_SPECIFIED
)
1316 /* force all ports active "the legacy way" */
1317 ChangePciConfig2(0x92, (a
| 0x0f));
1318 /* enable PCI interrupt */
1319 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1321 if(!(ChipFlags
& UNIATA_AHCI
)) {
1322 /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
1323 GetPciConfig1(0x90, tmp8
);
1324 if(!(tmp8
& 0x04)) {
1325 /* XXX SOS should be in intel_allocate if we grow it */
1326 if(c
== CHAN_NOT_SPECIFIED
) {
1327 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1328 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1331 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1336 /* enable PCI interrupt */
1337 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1341 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1343 if(c
== CHAN_NOT_SPECIFIED
) {
1344 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1345 chan
= &deviceExtension
->chan
[c
];
1346 GetPciConfig2(0x54, reg54
);
1347 if( ((reg54
>> (channel
*2)) & 30) != 30) {
1348 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1352 chan
= &deviceExtension
->chan
[c
];
1353 GetPciConfig2(0x54, reg54
);
1354 if( ((reg54
>> (channel
*2)) & 30) != 30) {
1355 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1359 case ATA_NVIDIA_ID
: {
1360 if(ChipFlags
& UNIATA_SATA
) {
1361 if(c
== CHAN_NOT_SPECIFIED
) {
1362 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
1363 /* enable control access */
1364 ChangePciConfig1(0x50, (a
| 0x04));
1365 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
1366 if(ChipFlags
& NVQ
) {
1367 /* clear interrupt status */
1368 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
1369 /* enable device and PHY state change interrupts */
1370 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
1371 /* disable NCQ support */
1372 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
1373 AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
1375 /* clear interrupt status */
1376 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
1377 /* enable device and PHY state change interrupts */
1378 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
1380 /* enable PCI interrupt */
1381 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1383 //UniataSataPhyEnable(HwDeviceExtension, c);
1388 // check 80-pin cable
1389 if(c
== CHAN_NOT_SPECIFIED
) {
1391 /* set prefetch, postwrite */
1392 ChangePciConfig1(0x51, (a
& 0x0f));
1394 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1395 chan
= &deviceExtension
->chan
[c
];
1396 GetPciConfig1(0x52, reg52
);
1397 if( !((reg52
>> (channel
*2)) & 0x01)) {
1398 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1402 chan
= &deviceExtension
->chan
[c
];
1403 GetPciConfig1(0x52, reg52
);
1404 if( !((reg52
>> (channel
*2)) & 0x01)) {
1405 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1410 case ATA_PROMISE_ID
: {
1415 if(c
== CHAN_NOT_SPECIFIED
) {
1416 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
1417 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
1418 AtapiReadPortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
1422 /* enable burst mode */
1423 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
1424 if(c
== CHAN_NOT_SPECIFIED
) {
1425 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
1426 AtapiReadPortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
1427 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1428 chan
= &deviceExtension
->chan
[c
];
1429 GetPciConfig2(0x50, Reg50
);
1430 if(Reg50
& (1 << (channel
+10))) {
1431 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1435 chan
= &deviceExtension
->chan
[c
];
1436 GetPciConfig2(0x50, Reg50
);
1437 if(Reg50
& (1 << (channel
+10))) {
1438 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1443 if(c
== CHAN_NOT_SPECIFIED
) {
1444 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1445 chan
= &deviceExtension
->chan
[c
];
1446 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
1447 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
1448 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1452 chan
= &deviceExtension
->chan
[c
];
1453 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
1454 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
1455 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1460 if(c
== CHAN_NOT_SPECIFIED
) {
1461 if(ChipFlags
& PRSATA
) {
1462 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x6c, 0x000000ff);
1464 for(c
=0; c
<4; c
++) {
1465 chan
= &deviceExtension
->chan
[c
];
1466 AtapiWritePort4(chan
, IDX_BM_Command
,
1467 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
1468 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
1469 if(chan
->MaxTransferMode
< ATA_SA150
&&
1470 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
1471 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1475 chan
= &deviceExtension
->chan
[c
];
1476 AtapiWritePort4(chan
, IDX_BM_Command
,
1477 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
1478 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
1479 if(chan
->MaxTransferMode
< ATA_SA150
&&
1480 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
1481 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1487 case ATA_SERVERWORKS_ID
:
1488 if(c
== CHAN_NOT_SPECIFIED
) {
1489 if(ChipType
== SWKS33
) {
1490 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1491 SystemIoBusNumber
, slotNumber
);
1493 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
1498 if(ChipType
== SIIMIO
) {
1499 KdPrint2((PRINT_PREFIX
"ATI New\n"));
1502 KdPrint2((PRINT_PREFIX
"ATI\n"));
1505 case ATA_SILICON_IMAGE_ID
:
1506 /* if(ChipFlags & SIIENINTR) {
1507 SetPciConfig1(0x71, 0x01);
1512 KdPrint2((PRINT_PREFIX
"SII\n"));
1515 if(c
== CHAN_NOT_SPECIFIED
) {
1516 if(ChipFlags
& SIISETCLK
) {
1517 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
1518 GetPciConfig1(0x8a, tmp8
);
1519 if ((tmp8
& 0x30) != 0x10)
1520 ChangePciConfig1(0x8a, (a
& 0xcf | 0x10));
1521 GetPciConfig1(0x8a, tmp8
);
1522 if ((tmp8
& 0x30) != 0x10) {
1523 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
1524 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1528 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
1529 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
1530 if(c
== CHAN_NOT_SPECIFIED
) {
1531 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1532 chan
= &deviceExtension
->chan
[c
];
1533 GetPciConfig2(0x79, Reg79
);
1534 if(Reg79
& (channel
? 0x02 : 0x01)) {
1535 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1539 chan
= &deviceExtension
->chan
[c
];
1540 GetPciConfig2(0x79, Reg79
);
1541 if(Reg79
& (channel
? 0x02 : 0x01)) {
1542 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1546 ULONG unit01
= (c
& 1);
1547 ULONG unit10
= (c
& 2);
1548 /* enable/disable PHY state change interrupt */
1549 if(c
== CHAN_NOT_SPECIFIED
) {
1550 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1553 if(ChipFlags
& SIINOSATAIRQ
) {
1554 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
1555 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
1559 if(ChipFlags
& SIINOSATAIRQ
) {
1560 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
1561 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
1563 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
1564 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
1568 if(c
== CHAN_NOT_SPECIFIED
) {
1569 /* enable interrupt as BIOS might not */
1570 ChangePciConfig1(0x8a, (a
& 0x3f));
1571 // Enable 3rd and 4th channels
1572 if (ChipFlags
& SII4CH
) {
1573 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
1574 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
1577 chan
= &deviceExtension
->chan
[c
];
1578 /* dont block interrupts */
1579 //ChangePciConfig4(0x48, (a & ~0x03c00000));
1580 tmp32
= AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
1581 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
1583 tmp32
= AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
1585 /* Initialize FIFO PCI bus arbitration */
1586 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
1588 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp32
));
1590 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
1592 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
1599 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
1600 if(c
== CHAN_NOT_SPECIFIED
) {
1601 /* Setup interrupts. */
1602 SetPciConfig1(0x71, 0x01);
1604 /* GetPciConfig1(0x8a, tmp8);
1606 SetPciConfig1(0x71, tmp8);*/
1608 /* Use MEMORY READ LINE for reads.
1609 * NOTE: Although not mentioned in the PCI0646U specs,
1610 * these bits are write only and won't be read
1611 * back as set or not. The PCI0646U2 specs clarify
1615 SetPciConfig1(0x71, tmp8);
1617 /* Set reasonable active/recovery/address-setup values. */
1618 SetPciConfig1(0x53, 0x40);
1619 SetPciConfig1(0x54, 0x3f);
1620 SetPciConfig1(0x55, 0x40);
1621 SetPciConfig1(0x56, 0x3f);
1622 SetPciConfig1(0x57, 0x1c);
1623 SetPciConfig1(0x58, 0x3f);
1624 SetPciConfig1(0x5b, 0x3f);
1631 if(c
== CHAN_NOT_SPECIFIED
) {
1637 ChangePciConfig1(0x52, (a
& ~0x04));
1641 ChangePciConfig1(0x49, (a
& ~0x01));
1644 ChangePciConfig2(0x50, (a
| 0x0008));
1645 ChangePciConfig2(0x52, (a
| 0x0008));
1648 ChangePciConfig2(0x04, (a
& ~0x0400));
1651 if(ChipType
== SIS133NEW
) {
1653 if(c
== CHAN_NOT_SPECIFIED
) {
1654 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1655 chan
= &deviceExtension
->chan
[c
];
1656 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
1657 if(tmp16
& 0x8000) {
1658 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1662 chan
= &deviceExtension
->chan
[c
];
1663 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
1664 if(tmp16
& 0x8000) {
1665 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1669 if(c
== CHAN_NOT_SPECIFIED
) {
1670 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1671 chan
= &deviceExtension
->chan
[c
];
1672 GetPciConfig1(48, tmp8
);
1673 if(tmp8
& (0x10 << channel
)) {
1674 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1678 chan
= &deviceExtension
->chan
[c
];
1679 GetPciConfig1(48, tmp8
);
1680 if(tmp8
& (0x10 << channel
)) {
1681 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1688 if(c
== CHAN_NOT_SPECIFIED
) {
1689 /* prepare for ATA-66 on the 82C686a and 82C596b */
1690 if(ChipFlags
& VIACLK
) {
1691 ChangePciConfig4(0x50, (a
| 0x030b030b));
1694 if(ChipFlags
& UNIATA_SATA
) {
1695 /* enable PCI interrupt */
1696 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1700 // check 80-pin cable
1701 if(c
== CHAN_NOT_SPECIFIED
) {
1702 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1703 chan
= &deviceExtension
->chan
[c
];
1704 if(!via_cable80(deviceExtension
, channel
)) {
1705 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1709 chan
= &deviceExtension
->chan
[c
];
1710 if(!via_cable80(deviceExtension
, channel
)) {
1711 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1715 if(c
== CHAN_NOT_SPECIFIED
) {
1716 /* the southbridge might need the data corruption fix */
1717 if(ChipFlags
& VIABUG
) {
1718 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1719 SystemIoBusNumber
, slotNumber
);
1721 /* set prefetch, postwrite */
1722 if(ChipType
!= VIA133
) {
1723 ChangePciConfig1(0x41, (a
| 0xf0));
1726 /* set fifo configuration half'n'half */
1727 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
1729 /* set status register read retry */
1730 ChangePciConfig1(0x44, (a
| 0x08));
1732 /* set DMA read & end-of-sector fifo flush */
1733 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
1735 /* set sector size */
1736 SetPciConfig2(0x60, DEV_BSIZE
);
1737 SetPciConfig2(0x68, DEV_BSIZE
);
1744 if(ChipType
== ITE_33
)
1746 if(c
== CHAN_NOT_SPECIFIED
) {
1747 /* set PCI mode and 66Mhz reference clock */
1748 ChangePciConfig1(0x50, a
& ~0x83);
1750 /* set default active & recover timings */
1751 SetPciConfig1(0x54, 0x31);
1752 SetPciConfig1(0x56, 0x31);
1755 GetPciConfig2(0x40, tmp16
);
1756 // check 80-pin cable
1757 if(c
== CHAN_NOT_SPECIFIED
) {
1758 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1759 chan
= &deviceExtension
->chan
[c
];
1760 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
1761 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1765 chan
= &deviceExtension
->chan
[c
];
1766 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
1767 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1775 } // end AtapiChipInit()
1779 IN PHW_DEVICE_EXTENSION deviceExtension
,
1780 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
1788 if(!BaseIoAddressBM_0
) {
1791 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1792 chan
= &deviceExtension
->chan
[c
];
1793 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
1794 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONG
)BaseIoAddressBM_0
+ i
) : 0;
1795 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
1797 if(BaseIoAddressBM_0
) {
1798 BaseIoAddressBM_0
++;
1801 } // end UniataInitMapBM()
1805 IN PHW_CHANNEL chan
,
1806 IN PIDE_REGISTERS_1 BaseIoAddress1
,
1807 IN PIDE_REGISTERS_2 BaseIoAddress2
1812 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
1813 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONG
)BaseIoAddress1
+ i
) : 0;
1814 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
1816 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
1817 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONG
)BaseIoAddress2
+ i
) : 0;
1818 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
1820 UniataInitSyncBaseIO(chan
);
1821 } // end UniataInitMapBase()
1824 UniataInitSyncBaseIO(
1828 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
1829 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
1830 } // end UniataInitSyncBaseIO()