3 Copyright (c) 2004-2008 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 case ATA_ACER_LABS_ID
:
67 switch(deviceExtension
->DevID
) {
70 deviceExtension
->NumberChannels
= 4;
71 KdPrint2((PRINT_PREFIX
"Acer 4 chan\n"));
76 if(ChipType
!= PRMIO
) {
79 deviceExtension
->NumberChannels
= 4;
80 KdPrint2((PRINT_PREFIX
"Promise 4 chan\n"));
83 KdPrint2((PRINT_PREFIX
"Marvell\n"));
84 switch(deviceExtension
->DevID
) {
86 /* 88SX6101 only have 1 PATA channel */
87 if(BMList
[deviceExtension
->DevIndex
].channel
) {
88 KdPrint2((PRINT_PREFIX
"88SX6101 has no 2nd PATA chan\n"));
91 deviceExtension
->NumberChannels
= 1;
92 KdPrint2((PRINT_PREFIX
"88SX6101 PATA 1 chan\n"));
97 KdPrint2((PRINT_PREFIX
"ATI\n"));
98 switch(deviceExtension
->DevID
) {
101 /* IXP600 & IXP700 only have 1 PATA channel */
102 if(BMList
[deviceExtension
->DevIndex
].channel
) {
103 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
106 deviceExtension
->NumberChannels
= 1;
107 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
110 case ATA_SILICON_IMAGE_ID
:
112 if(ChipFlags
& SIIBUG
) {
114 if(ChipType
!= SIIMIO
) {
121 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
122 KdPrint2((PRINT_PREFIX
"New SII\n"));
124 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
126 if(deviceExtension
->HwFlags
& SII4CH
) {
127 deviceExtension
->NumberChannels
= 4;
128 KdPrint2((PRINT_PREFIX
"4 chan\n"));
132 if((deviceExtension
->DevID
== 0x32491106) &&
133 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[5].RangeStart
)) {
134 deviceExtension
->NumberChannels
= 3;
135 KdPrint2((PRINT_PREFIX
"VIA 3 chan\n"));
138 } // end switch(VendorID)
141 } // end UniataChipDetectChannels()
146 IN PVOID HwDeviceExtension
,
147 IN PPCI_COMMON_CONFIG pciData
, // optional
148 IN ULONG DeviceNumber
,
149 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
150 IN BOOLEAN
* simplexOnly
153 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
154 ULONG slotNumber
= deviceExtension
->slotNumber
;
155 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
156 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
157 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
158 ULONG RevID
= deviceExtension
->RevID
;
160 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
166 ULONG BaseMemAddress
;
167 ULONG BaseIoAddress1
;
168 ULONG BaseIoAddress2
;
169 ULONG BaseIoAddressBM
;
170 BOOLEAN MemIo
= FALSE
;
172 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
173 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
175 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
177 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
183 BaseIoAddressBM
= pciData
->u
.type0
.BaseAddresses
[4] & ~0x07;
184 deviceExtension
->MaxTransferMode
= BaseIoAddressBM
? ATA_DMA
: ATA_PIO4
;
185 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
186 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
188 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
189 if(i
!= BMLIST_TERMINATOR
) {
190 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
192 KdPrint2((PRINT_PREFIX
" unknown dev, BM addr %#x", BaseIoAddressBM
));
194 KdPrint2((PRINT_PREFIX
" MaxTransferMode %#x\n", deviceExtension
->MaxTransferMode
));
196 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
199 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
206 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
207 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
208 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
209 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
210 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
211 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
212 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
213 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
215 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
216 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
217 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
218 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
220 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
221 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),*/
222 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
223 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
224 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
225 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
226 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
227 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
229 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
230 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
231 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
233 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
234 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
236 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
237 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
238 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
239 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
240 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
241 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
244 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
245 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
246 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
247 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
248 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
249 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
250 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
251 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
252 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
253 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
254 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
255 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
256 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
257 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| VIAAST
),
258 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| VIAAST
),
259 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| VIAAST
),
260 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6
, "VIA 8237A" , VIA133
| VIAAST
),
261 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8251" , VIA133
| VIAAST
),
262 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
265 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
266 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH
),
267 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH
),
268 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH
),
269 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH
),
270 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
273 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
278 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
279 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
280 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
281 if(i
!= BMLIST_TERMINATOR
) {
282 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
287 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
288 // New chips have own DeviceId
289 if(deviceExtension
->DevID
!= ATA_VIA82C571
)
291 // Old chips have same DeviceId, we can distinguish between them
292 // only by SouthBridge DeviceId
293 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
294 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, slotNumber
, NULL
);
295 if(i
!= BMLIST_TERMINATOR
) {
296 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
297 deviceExtension
->HwFlags
|= VIASOUTH
;
299 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
300 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, slotNumber
, NULL
);
301 if(i
!= BMLIST_TERMINATOR
) {
302 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
312 KdPrint2((PRINT_PREFIX
"Default\n"));
314 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
315 /* do extra chipset specific setups */
316 switch(deviceExtension
->DevID
) {
318 //case ATA_CYPRESS_ID:
319 case 0xc6931080: /* 82c693 ATA controller */
320 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
323 case 0x000116ca: /* Cenatek Rocket Drive controller */
324 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
327 /* case ATA_CYRIX_ID:
328 DevTypeInfo = &CyrixAdapters[0];
330 case 0x01021078: /* Cyrix 5530 ATA33 controller */
331 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
334 case 0x06401039: /* CMD 640 known bad, no DMA */
340 case 0x10001042: /* RZ 100x known bad, no DMA */
343 if(deviceExtension
->BaseIoAddressBM_0
)
344 ScsiPortFreeDeviceBase(HwDeviceExtension
,
345 deviceExtension
->BaseIoAddressBM_0
);
347 deviceExtension
->BaseIoAddressBM_0
= 0;
348 deviceExtension
->BusMaster
= FALSE
;
349 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
352 case 0x81721283: /* IT8172 IDE controller */
353 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
364 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
366 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
367 if(i
== BMLIST_TERMINATOR
) {
370 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
371 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
373 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
375 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
376 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
377 deviceExtension
->HwFlags
= tmp32
;
379 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
380 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
381 deviceExtension
->HwFlags
|= tmp32
;
383 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
384 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
385 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
389 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
390 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
391 if(tmp32
!= 0xffffffff) {
392 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
393 deviceExtension
->MaxTransferMode
= tmp32
;
396 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
397 deviceExtension
->HwFlags
|= UNIATA_SATA
;
400 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
401 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
403 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
404 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
406 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
409 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
414 case ATA_ACER_LABS_ID
:
415 if(ChipFlags
& UNIATA_SATA
) {
416 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
417 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
419 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
421 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
422 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
423 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
424 //ULONG unit01 = (c & 1);
425 ULONG unit10
= (c
& 2);
426 chan
= &deviceExtension
->chan
[c
];
428 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
429 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
431 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
432 UniataInitSyncBaseIO(chan
);
434 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
435 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
438 // SATA not supported yet
440 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
441 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
442 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
444 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
449 if(ChipFlags
& UNIATA_SATA
) {
450 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
451 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
452 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
453 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
454 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
455 KdPrint2((PRINT_PREFIX
"MemIo\n"));
458 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
459 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
460 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
461 chan
= &deviceExtension
->chan
[c
];
463 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
464 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
465 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
466 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
467 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
468 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
470 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
476 if(ChipType
!= PRMIO
) {
482 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
483 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
485 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
486 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
487 KdPrint2((PRINT_PREFIX
"MemIo\n"));
490 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
491 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
492 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
496 chan
= &deviceExtension
->chan
[c
];
501 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
502 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs12
;
503 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
505 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
506 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
508 UniataInitSyncBaseIO(chan
);
510 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
511 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
512 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
513 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
514 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
515 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
520 KdPrint2((PRINT_PREFIX
"ATI\n"));
521 case ATA_SILICON_IMAGE_ID
: {
523 if(ChipFlags
& SIIBUG
) {
525 if(ChipType
!= SIIMIO
) {
532 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
533 KdPrint2((PRINT_PREFIX
"New SII\n"));
535 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
537 //if(deviceExtension->HwFlags & SII4CH) {
538 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
540 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
542 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
543 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
544 KdPrint2((PRINT_PREFIX
"MemIo\n"));
547 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
548 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
550 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
551 ULONG unit01
= (c
& 1);
552 ULONG unit10
= (c
& 2);
554 chan
= &deviceExtension
->chan
[c
];
556 if(deviceExtension
->AltRegMap
) {
557 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
558 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
559 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
561 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
562 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
563 UniataInitSyncBaseIO(chan
);
565 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
566 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
567 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
568 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
569 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
570 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
571 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
572 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
573 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
574 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
575 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
576 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
579 if(ChipFlags
& UNIATA_SATA
) {
580 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
581 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
582 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
583 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
584 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
585 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
587 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
592 case ATA_SERVERWORKS_ID
: {
594 if(ChipType
!= SWKSMIO
) {
601 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
603 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
604 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
606 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
607 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
608 KdPrint2((PRINT_PREFIX
"MemIo\n"));
611 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
612 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
614 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
615 ULONG offs
= c
*0x100;
617 chan
= &deviceExtension
->chan
[c
];
618 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
619 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
620 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
622 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
623 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
624 UniataInitSyncBaseIO(chan
);
626 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
627 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
628 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
629 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
630 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
631 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
633 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
634 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
635 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
636 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
637 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
638 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
640 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
645 //if(ChipType != SIS_SOUTH) {
646 BOOLEAN SIS_182
=FALSE
;
648 if(!(ChipFlags
& SIS_BASE
)) {
649 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
650 //PrintNtConsole("Found SIS_SOUTH\n");
653 // Make some additional checks
654 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
655 ChangePciConfig1(0x57, (a
& 0x7f));
656 GetPciConfig4(0x00, tmp32
);
657 if(tmp32
== ATA_SIS5518
) {
658 ChipType
= SIS133NEW
;
659 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
660 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
661 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
662 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
664 ChangePciConfig1(0x57, (a
| 0x80));
666 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
667 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
668 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
669 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, -1, NULL
, -1 )
672 GetPciConfig1(0x4a, tmp8
);
673 ChangePciConfig1(0x4a, (a
| 0x10));
674 if(tmp32
== ATA_SIS5513
||
675 tmp32
== ATA_SIS5517
) {
676 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
677 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
678 if(i
!= BMLIST_TERMINATOR
) {
679 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
680 //deviceExtension->MaxTransferMode = ATA_UDMA6;
681 deviceExtension
->MaxTransferMode
= SiSSouthAdapters
[i
].MaxTransferMode
;
682 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
683 deviceExtension
->HwFlags
|= UNIATA_SATA
;
684 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182) {
689 // SiS-South not found
690 if(tmp32
== ATA_SIS5517
) {
691 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
692 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
695 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
700 SetPciConfig1(0x4a, tmp8
);
701 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
702 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
703 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
704 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
706 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
708 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
709 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
710 KdPrint2((PRINT_PREFIX
"MemIo\n"));
713 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
714 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
716 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
717 ULONG offs
= c
<< (SIS_182
? 5 : 6);
719 chan
= &deviceExtension
->chan
[c
];
720 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
721 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
722 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
723 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
724 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
725 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
727 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
731 //ChangePciConfig1(0x57, (a | 0x80));
736 if(ChipFlags
& UNIATA_SATA
) {
739 ULONG BaseMemAddress
= 0;
742 case 0x3149: // VIA 6420
743 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
746 case 0x3249: // VIA 6421
747 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
752 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
753 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
754 5, 0, IoSize
* deviceExtension
->NumberChannels
);
755 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
756 KdPrint2((PRINT_PREFIX
"MemIo\n"));
759 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
760 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
762 if(/*deviceExtension->*/BaseMemAddress
) {
763 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
764 if(ChipFlags
& VIABAR
) {
766 ULONG BaseIoAddressBM_0
;
769 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
770 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
771 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
772 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
773 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
774 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
776 chan
= &deviceExtension
->chan
[c
];
778 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, 0x80);
780 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
781 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
783 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2 + FIELD_OFFSET(IDE_REGISTERS_2
, AltStatus
);
784 UniataInitSyncBaseIO(chan
);
786 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
787 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
790 // Do not setup SATA registers for PATA part
791 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
792 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
793 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
794 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
795 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
796 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
798 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
808 if(!(ChipFlags
& UNIATA_SATA
)) {
812 /* the intel 31244 needs special care if in DPA mode */
813 if(DeviceID
== 3200 && // Intel 31244
814 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
816 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
817 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
819 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
820 KdPrint2((PRINT_PREFIX
"MemIo\n"));
823 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
824 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
825 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
827 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
828 ULONG offs
= 0x200 + c
*0x200;
830 chan
= &deviceExtension
->chan
[c
];
831 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
832 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
833 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
836 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
837 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
838 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
839 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
840 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
841 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
842 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
843 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
845 UniataInitSyncBaseIO(chan
);
847 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
848 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
849 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
851 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
852 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
854 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
855 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
856 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
857 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
858 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
859 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
861 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
862 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
863 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
864 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
865 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
866 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
868 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
873 /* SATA parts can be either compat or AHCI */
874 if(ChipFlags
& UNIATA_AHCI
) {
876 GetPciConfig1(0x90, tmp8
);
878 KdPrint2((PRINT_PREFIX
"AHCI not supported yet\n"));
881 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
884 if(ChipFlags
& UNIATA_SATA
) {
885 //BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
887 BaseMemAddress
= NULL
; // HACK-HACK
888 if(!BaseMemAddress
) {
889 KdPrint2((PRINT_PREFIX
"Intel: no SATA I/O space, operate in PATA Compatible mode\n"));
890 deviceExtension
->HwFlags
&= ~UNIATA_SATA
;
893 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
894 KdPrint2((PRINT_PREFIX
"MemIo\n"));
897 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
898 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
903 /* Cyrix 5530 ATA33 controller */
904 if(deviceExtension
->DevID
== 0x01021078) {
905 ConfigInfo
->AlignmentMask
= 0x0f;
906 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
913 } // end UniataChipDetect()
917 Do some 'magic staff' for VIA SouthBridge
918 This will prevent data losses
922 AtapiViaSouthBridgeFixup(
923 IN PVOID HwDeviceExtension
,
924 IN BUS_DATA_TYPE BusDataType
,
925 IN ULONG SystemIoBusNumber
,
929 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
930 PCI_COMMON_CONFIG pciData
;
936 PCI_SLOT_NUMBER slotData
;
938 BOOLEAN found
= FALSE
;
940 slotData
.u
.AsULONG
= slotNumber
;
941 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
943 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
945 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
950 PCI_COMMON_HDR_LENGTH
);
952 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
956 VendorID
= pciData
.VendorID
;
957 DeviceID
= pciData
.DeviceID
;
958 dev_id
= (VendorID
| (DeviceID
<< 16));
960 if (dev_id
== 0x03051106 || /* VIA VT8363 */
961 dev_id
== 0x03911106 || /* VIA VT8371 */
962 dev_id
== 0x31021106 || /* VIA VT8662 */
963 dev_id
== 0x31121106) { /* VIA VT8361 */
966 GetPciConfig1(0x76, reg76
);
968 if ((reg76
& 0xf0) != 0xd0) {
969 SetPciConfig1(0x75, 0x80);
970 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
977 deviceExtension
->HwFlags
&= ~VIABUG
;
979 } // end AtapiViaSouthBridgeFixup()
982 Do some 'magic staff' for ROSB SouthBridge
983 This will prevent data losses
987 AtapiRosbSouthBridgeFixup(
988 IN PVOID HwDeviceExtension
,
989 IN BUS_DATA_TYPE BusDataType
,
990 IN ULONG SystemIoBusNumber
,
994 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
995 PCI_COMMON_CONFIG pciData
;
1001 PCI_SLOT_NUMBER slotData
;
1003 // BOOLEAN found = FALSE;
1005 /* locate the ISA part in the southbridge and enable UDMA33 */
1006 slotData
.u
.AsULONG
= slotNumber
;
1007 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1009 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1011 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1016 PCI_COMMON_HDR_LENGTH
);
1018 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1022 VendorID
= pciData
.VendorID
;
1023 DeviceID
= pciData
.DeviceID
;
1024 dev_id
= (VendorID
| (DeviceID
<< 16));
1026 if (dev_id
== ATA_ROSB4_ISA
) { /* VIA VT8361 */
1027 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1031 } // end AtapiRosbSouthBridgeFixup()
1034 Do some 'magic staff' for ROSB SouthBridge
1035 This will prevent data losses
1039 AtapiAliSouthBridgeFixup(
1040 IN PVOID HwDeviceExtension
,
1041 IN BUS_DATA_TYPE BusDataType
,
1042 IN ULONG SystemIoBusNumber
,
1043 IN ULONG slotNumber
,
1047 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1048 PCI_COMMON_CONFIG pciData
;
1054 PCI_SLOT_NUMBER slotData
;
1056 // BOOLEAN found = FALSE;
1058 /* workaround for datacorruption bug found on at least SUN Blade-100
1059 * find the ISA function on the southbridge and disable then enable
1060 * the ATA channel tristate buffer */
1061 slotData
.u
.AsULONG
= slotNumber
;
1062 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1064 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1066 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1071 PCI_COMMON_HDR_LENGTH
);
1073 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1077 VendorID
= pciData
.VendorID
;
1078 DeviceID
= pciData
.DeviceID
;
1079 dev_id
= (VendorID
| (DeviceID
<< 16));
1081 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1082 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1083 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1087 } // end AtapiRosbSouthBridgeFixup()
1092 IN PHW_DEVICE_EXTENSION deviceExtension
,
1093 IN ULONG channel
// physical channel number (0-1)
1096 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1097 ULONG slotNumber
= deviceExtension
->slotNumber
;
1098 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1100 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1102 UCHAR reg
, val
, res
;
1103 PCI_SLOT_NUMBER slotData
;
1105 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1107 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1108 reg
= channel
? 0x57 : 0x53;
1109 GetPciConfig1(reg
, val
);
1110 SetPciConfig1(reg
, val
| 0x80);
1114 GetPciConfig1(reg
, val
);
1115 SetPciConfig1(reg
, val
& 0xfe);
1117 GetPciConfig1(0x5a, res
);
1118 res
= res
& (channel
? 0x01 : 0x02);
1119 SetPciConfig1(reg
, val
);
1121 } // end hpt_cable80()
1127 IN PHW_DEVICE_EXTENSION deviceExtension
,
1128 IN ULONG channel
// physical channel number (0-1)
1131 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1132 ULONG slotNumber
= deviceExtension
->slotNumber
;
1133 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1135 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1142 GetPciConfig1(0x50, reg50
);
1159 for (j
=0; j
>=2; i
-= 8) {
1160 i
= (3-(channel
*2+j
))*8;
1161 if (((reg50
>> (i
& 0x10)) & 8) &&
1162 ((reg50
>> i
) & 0x20) &&
1163 (((reg50
>> i
) & 7) < a
)) {
1165 res
|= TRUE
; //(1 << (1 - (i >> 4)));
1170 } // end via_cable80()
1175 IN PHW_DEVICE_EXTENSION deviceExtension
,
1176 IN ULONG channel
, // physical channel number (0-1)
1181 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1182 ULONG slotNumber
= deviceExtension
->slotNumber
;
1183 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1185 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1187 ULONG c
; // logical channel (for Compatible Mode controllers)
1190 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1191 chan
= &deviceExtension
->chan
[c
];
1193 GetPciConfig1(pci_reg
, tmp8
);
1194 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1195 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1200 } // end generic_cable80()
1204 UniAtaReadLunConfig(
1205 IN PHW_DEVICE_EXTENSION deviceExtension
,
1206 IN ULONG channel
, // physical channel
1212 PHW_LU_EXTENSION LunExt
;
1215 c
= channel
- deviceExtension
->Channel
; // logical channel
1217 chan
= &deviceExtension
->chan
[c
];
1219 LunExt
= &(deviceExtension
->lun
[c
*2+ldev
]);
1221 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"ReadCacheEnable", 1);
1222 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1224 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"WriteCacheEnable", 1);
1225 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1227 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1228 LunExt
->opt_MaxTransferMode
= tmp32
;
1230 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"PreferedTransferMode", 0xffffffff);
1231 LunExt
->opt_PreferedTransferMode
= tmp32
;
1233 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"ReadOnly", 0);
1235 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1238 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"GeomType", 0xffffffff);
1242 LunExt
->opt_GeomType
= tmp32
;
1244 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"Hidden", 0);
1246 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1250 } // end UniAtaReadLunConfig()
1254 AtapiReadChipConfig(
1255 IN PVOID HwDeviceExtension
,
1256 IN ULONG DeviceNumber
,
1257 IN ULONG channel
// physical channel
1260 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1263 ULONG c
; // logical channel (for Compatible Mode controllers)
1265 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1266 ASSERT(deviceExtension
);
1268 if(channel
!= CHAN_NOT_SPECIFIED
) {
1269 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1271 c
= CHAN_NOT_SPECIFIED
;
1274 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1276 if(channel
== CHAN_NOT_SPECIFIED
) {
1277 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1278 deviceExtension
->simplexOnly
= TRUE
;
1280 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1281 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1282 deviceExtension
->opt_AtapiDmaRawRead
= TRUE
;
1283 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1286 if(c
== CHAN_NOT_SPECIFIED
) {
1287 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1288 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1289 chan
= &deviceExtension
->chan
[c
];
1290 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1291 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1292 if(tmp32
!= 0xffffffff) {
1293 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1294 chan
->MaxTransferMode
= tmp32
;
1296 //UniAtaReadLunConfig(deviceExtension, c, 0);
1297 //UniAtaReadLunConfig(deviceExtension, c, 1);
1300 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1301 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1304 deviceExtension
->opt_AtapiDmaControlCmd
=
1305 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1308 deviceExtension
->opt_AtapiDmaRawRead
=
1309 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1312 deviceExtension
->opt_AtapiDmaReadWrite
=
1313 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1317 chan
= &deviceExtension
->chan
[c
];
1318 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1319 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1320 if(tmp32
!= 0xffffffff) {
1321 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1322 chan
->MaxTransferMode
= tmp32
;
1324 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1325 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1327 UniAtaReadLunConfig(deviceExtension
, channel
, 0);
1328 UniAtaReadLunConfig(deviceExtension
, channel
, 1);
1332 } // end AtapiReadChipConfig()
1337 IN PVOID HwDeviceExtension
,
1338 IN ULONG DeviceNumber
,
1339 IN ULONG channel
// physical channel
1342 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1343 ULONG slotNumber
= deviceExtension
->slotNumber
;
1344 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1345 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1347 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1349 ULONG RevID
= deviceExtension
->RevID
;
1351 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1352 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1353 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1358 ULONG c
; // logical channel (for Compatible Mode controllers)
1359 BOOLEAN CheckCable
= FALSE
;
1360 //ULONG BaseIoAddress;
1363 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1366 case CHAN_NOT_SPECIFIED
:
1367 c
= CHAN_NOT_SPECIFIED
;
1370 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1373 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1375 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1376 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1378 if(deviceExtension
->UnknownDev
) {
1379 KdPrint2((PRINT_PREFIX
" Unknown chip, exiting\n" ));
1381 VendorID
= 0xffffffff;
1385 // case ATA_ACARD_ID:
1387 case ATA_ACER_LABS_ID
:
1388 if(ChipFlags
& UNIATA_SATA
) {
1389 if(c
== CHAN_NOT_SPECIFIED
) {
1390 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1391 chan
= &deviceExtension
->chan
[c
];
1392 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1393 /* the southbridge might need the data corruption fix */
1394 if(RevID
== 0xc2 || RevID
== 0xc3) {
1395 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1396 SystemIoBusNumber
, slotNumber
, c
);
1399 /* enable PCI interrupt */
1400 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1403 if(ChipFlags
& ALINEW
) {
1404 if(c
== CHAN_NOT_SPECIFIED
) {
1405 /* use device interrupt as byte count end */
1406 ChangePciConfig1(0x4a, (a
| 0x20));
1407 /* enable cable detection and UDMA support on newer chips */
1408 ChangePciConfig1(0x4b, (a
| 0x09));
1410 /* enable ATAPI UDMA mode */
1411 ChangePciConfig1(0x53, (a
| 0x01));
1414 // check 80-pin cable
1415 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
1418 if(c
== CHAN_NOT_SPECIFIED
) {
1419 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1420 ChangePciConfig1(0x53, (a
| 0x03));
1423 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1428 if(c
== CHAN_NOT_SPECIFIED
) {
1429 /* set prefetch, postwrite */
1430 if(ChipFlags
& AMDBUG
) {
1431 ChangePciConfig1(0x41, (a
& 0x0f));
1433 ChangePciConfig1(0x41, (a
| 0xf0));
1436 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1438 // check 80-pin cable
1439 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
1440 if(c
== CHAN_NOT_SPECIFIED
) {
1443 generic_cable80(deviceExtension
, channel
, 0x42, 0);
1447 case ATA_HIGHPOINT_ID
:
1449 if(c
== CHAN_NOT_SPECIFIED
) {
1451 if(ChipFlags
& HPTOLD
) {
1452 /* turn off interrupt prediction */
1453 ChangePciConfig1(0x51, (a
& ~0x80));
1455 /* turn off interrupt prediction */
1456 ChangePciConfig1(0x51, (a
& ~0x03));
1457 ChangePciConfig1(0x55, (a
& ~0x03));
1458 /* turn on interrupts */
1459 ChangePciConfig1(0x5a, (a
& ~0x10));
1460 /* set clocks etc */
1461 if(ChipType
< HPT372
) {
1462 SetPciConfig1(0x5b, 0x22);
1464 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
1469 // check 80-pin cable
1470 chan
= &deviceExtension
->chan
[c
];
1471 if(!hpt_cable80(deviceExtension
, channel
)) {
1472 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1476 case ATA_INTEL_ID
: {
1478 if(ChipFlags
& UNIATA_SATA
) {
1479 if(c
!= CHAN_NOT_SPECIFIED
)
1482 /* force all ports active "the legacy way" */
1483 ChangePciConfig2(0x92, (a
| 0x0f));
1484 /* enable PCI interrupt */
1485 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1487 if(!(ChipFlags
& UNIATA_AHCI
)) {
1488 /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
1489 GetPciConfig1(0x90, tmp8
);
1490 if(!(tmp8
& 0x04)) {
1491 /* XXX SOS should be in intel_allocate if we grow it */
1492 if(c
== CHAN_NOT_SPECIFIED
) {
1493 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1494 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1497 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1502 /* enable PCI interrupt */
1503 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1507 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1509 // check 80-pin cable
1510 if(c
== CHAN_NOT_SPECIFIED
) {
1513 chan
= &deviceExtension
->chan
[c
];
1514 GetPciConfig2(0x54, reg54
);
1515 if( ((reg54
>> (channel
*2)) & 30) != 30) {
1516 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1520 case ATA_NVIDIA_ID
: {
1521 if(ChipFlags
& UNIATA_SATA
) {
1522 if(c
== CHAN_NOT_SPECIFIED
) {
1523 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
1524 /* enable control access */
1525 ChangePciConfig1(0x50, (a
| 0x04));
1526 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
1527 if(ChipFlags
& NVQ
) {
1528 /* clear interrupt status */
1529 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
1530 /* enable device and PHY state change interrupts */
1531 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
1532 /* disable NCQ support */
1533 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
1534 AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
1536 /* clear interrupt status */
1537 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
1538 /* enable device and PHY state change interrupts */
1539 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
1541 /* enable PCI interrupt */
1542 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1544 //UniataSataPhyEnable(HwDeviceExtension, c);
1549 if(c
== CHAN_NOT_SPECIFIED
) {
1550 /* set prefetch, postwrite */
1551 ChangePciConfig1(0x51, (a
& 0x0f));
1553 // check 80-pin cable
1554 generic_cable80(deviceExtension
, channel
, 0x52, 1);
1555 /* chan = &deviceExtension->chan[c];
1556 GetPciConfig1(0x52, reg52);
1557 if( !((reg52 >> (channel*2)) & 0x01)) {
1558 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1563 case ATA_PROMISE_ID
: {
1568 if(c
== CHAN_NOT_SPECIFIED
) {
1569 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
1570 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
1571 AtapiReadPortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
1575 /* enable burst mode */
1576 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
1577 if(c
== CHAN_NOT_SPECIFIED
) {
1578 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
1579 AtapiReadPortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
1581 // check 80-pin cable
1582 chan
= &deviceExtension
->chan
[c
];
1583 GetPciConfig2(0x50, Reg50
);
1584 if(Reg50
& (1 << (channel
+10))) {
1585 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1590 if(c
== CHAN_NOT_SPECIFIED
) {
1593 // check 80-pin cable
1594 chan
= &deviceExtension
->chan
[c
];
1595 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
1596 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
1597 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1602 if(c
== CHAN_NOT_SPECIFIED
) {
1603 if(ChipFlags
& PRSATA
) {
1604 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x6c, 0x000000ff);
1607 chan
= &deviceExtension
->chan
[c
];
1608 AtapiWritePort4(chan
, IDX_BM_Command
,
1609 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
1610 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
1611 // check 80-pin cable
1612 if(chan
->MaxTransferMode
< ATA_SA150
&&
1613 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
1614 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1620 case ATA_SERVERWORKS_ID
:
1621 if(c
== CHAN_NOT_SPECIFIED
) {
1622 if(ChipType
== SWKS33
) {
1623 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1624 SystemIoBusNumber
, slotNumber
);
1626 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
1631 if(ChipType
== SIIMIO
) {
1632 KdPrint2((PRINT_PREFIX
"ATI New\n"));
1635 KdPrint2((PRINT_PREFIX
"ATI\n"));
1638 case ATA_SILICON_IMAGE_ID
:
1639 /* if(ChipFlags & SIIENINTR) {
1640 SetPciConfig1(0x71, 0x01);
1645 KdPrint2((PRINT_PREFIX
"SII\n"));
1648 if(c
== CHAN_NOT_SPECIFIED
) {
1649 if(ChipFlags
& SIISETCLK
) {
1650 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
1651 GetPciConfig1(0x8a, tmp8
);
1652 if ((tmp8
& 0x30) != 0x10)
1653 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
1654 GetPciConfig1(0x8a, tmp8
);
1655 if ((tmp8
& 0x30) != 0x10) {
1656 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
1657 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1661 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
1662 // check 80-pin cable
1663 if(c
== CHAN_NOT_SPECIFIED
) {
1666 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
1667 chan
= &deviceExtension
->chan
[c
];
1668 GetPciConfig2(0x79, Reg79
);
1669 if(Reg79
& (channel
? 0x02 : 0x01)) {
1670 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1674 ULONG unit01
= (c
& 1);
1675 ULONG unit10
= (c
& 2);
1676 /* enable/disable PHY state change interrupt */
1677 if(c
== CHAN_NOT_SPECIFIED
) {
1678 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1681 if(ChipFlags
& SIINOSATAIRQ
) {
1682 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
1683 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
1687 if(ChipFlags
& SIINOSATAIRQ
) {
1688 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
1689 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
1691 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
1692 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
1696 if(c
== CHAN_NOT_SPECIFIED
) {
1697 /* enable interrupt as BIOS might not */
1698 ChangePciConfig1(0x8a, (a
& 0x3f));
1699 // Enable 3rd and 4th channels
1700 if (ChipFlags
& SII4CH
) {
1701 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
1702 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
1705 chan
= &deviceExtension
->chan
[c
];
1706 /* dont block interrupts */
1707 //ChangePciConfig4(0x48, (a & ~0x03c00000));
1708 tmp32
= AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
1709 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
1711 tmp32
= AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
1713 /* Initialize FIFO PCI bus arbitration */
1714 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
1716 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp32
));
1718 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
1720 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
1727 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
1728 if(c
== CHAN_NOT_SPECIFIED
) {
1729 /* Setup interrupts. */
1730 SetPciConfig1(0x71, 0x01);
1732 /* GetPciConfig1(0x8a, tmp8);
1734 SetPciConfig1(0x71, tmp8);*/
1736 /* Use MEMORY READ LINE for reads.
1737 * NOTE: Although not mentioned in the PCI0646U specs,
1738 * these bits are write only and won't be read
1739 * back as set or not. The PCI0646U2 specs clarify
1743 SetPciConfig1(0x71, tmp8);
1745 /* Set reasonable active/recovery/address-setup values. */
1746 SetPciConfig1(0x53, 0x40);
1747 SetPciConfig1(0x54, 0x3f);
1748 SetPciConfig1(0x55, 0x40);
1749 SetPciConfig1(0x56, 0x3f);
1750 SetPciConfig1(0x57, 0x1c);
1751 SetPciConfig1(0x58, 0x3f);
1752 SetPciConfig1(0x5b, 0x3f);
1759 if(c
== CHAN_NOT_SPECIFIED
) {
1765 ChangePciConfig1(0x52, (a
& ~0x04));
1769 ChangePciConfig1(0x49, (a
& ~0x01));
1772 ChangePciConfig2(0x50, (a
| 0x0008));
1773 ChangePciConfig2(0x52, (a
| 0x0008));
1776 ChangePciConfig2(0x04, (a
& ~0x0400));
1779 if(ChipType
== SIS133NEW
) {
1781 // check 80-pin cable
1782 if(c
== CHAN_NOT_SPECIFIED
) {
1785 chan
= &deviceExtension
->chan
[c
];
1786 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
1787 if(tmp16
& 0x8000) {
1788 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1792 // check 80-pin cable
1793 if(c
== CHAN_NOT_SPECIFIED
) {
1796 chan
= &deviceExtension
->chan
[c
];
1797 GetPciConfig1(48, tmp8
);
1798 if(tmp8
& (0x10 << channel
)) {
1799 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1806 if(c
== CHAN_NOT_SPECIFIED
) {
1807 /* prepare for ATA-66 on the 82C686a and 82C596b */
1808 if(ChipFlags
& VIACLK
) {
1809 ChangePciConfig4(0x50, (a
| 0x030b030b));
1812 if(ChipFlags
& UNIATA_SATA
) {
1813 /* enable PCI interrupt */
1814 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1818 /* the southbridge might need the data corruption fix */
1819 if(ChipFlags
& VIABUG
) {
1820 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1821 SystemIoBusNumber
, slotNumber
);
1823 /* set prefetch, postwrite */
1824 if(ChipType
!= VIA133
) {
1825 ChangePciConfig1(0x41, (a
| 0xf0));
1828 /* set fifo configuration half'n'half */
1829 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
1831 /* set status register read retry */
1832 ChangePciConfig1(0x44, (a
| 0x08));
1834 /* set DMA read & end-of-sector fifo flush */
1835 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
1837 /* set sector size */
1838 SetPciConfig2(0x60, DEV_BSIZE
);
1839 SetPciConfig2(0x68, DEV_BSIZE
);
1841 // check 80-pin cable
1842 chan
= &deviceExtension
->chan
[c
];
1843 if(!via_cable80(deviceExtension
, channel
)) {
1844 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1852 if(ChipType
== ITE_33
)
1854 if(c
== CHAN_NOT_SPECIFIED
) {
1855 /* set PCI mode and 66Mhz reference clock */
1856 ChangePciConfig1(0x50, a
& ~0x83);
1858 /* set default active & recover timings */
1859 SetPciConfig1(0x54, 0x31);
1860 SetPciConfig1(0x56, 0x31);
1862 // check 80-pin cable
1863 GetPciConfig2(0x40, tmp16
);
1864 chan
= &deviceExtension
->chan
[c
];
1865 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
1866 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1872 if(c
!= CHAN_NOT_SPECIFIED
) {
1873 // We don't know how to check for 80-pin cable on unknown controllers.
1874 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
1875 // So, leave this flag to use as hint in error recovery procedures
1876 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
1877 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
1882 // In all places separate channels are inited after common controller init
1883 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
1884 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
1885 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1886 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
1891 } // end AtapiChipInit()
1896 IN PHW_DEVICE_EXTENSION deviceExtension
,
1897 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
1905 if(!BaseIoAddressBM_0
) {
1908 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1909 chan
= &deviceExtension
->chan
[c
];
1910 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
1911 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONG
)BaseIoAddressBM_0
+ i
) : 0;
1912 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
1914 if(BaseIoAddressBM_0
) {
1915 BaseIoAddressBM_0
++;
1918 } // end UniataInitMapBM()
1923 IN PHW_CHANNEL chan
,
1924 IN PIDE_REGISTERS_1 BaseIoAddress1
,
1925 IN PIDE_REGISTERS_2 BaseIoAddress2
1930 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
1931 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONG
)BaseIoAddress1
+ i
) : 0;
1932 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
1934 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
1935 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONG
)BaseIoAddress2
+ i
) : 0;
1936 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
1938 UniataInitSyncBaseIO(chan
);
1939 } // end UniataInitMapBase()
1943 UniataInitSyncBaseIO(
1947 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
1948 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
1949 } // end UniataInitSyncBaseIO()