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
47 UniataChipDetectChannels(
48 IN PVOID HwDeviceExtension
,
49 IN PPCI_COMMON_CONFIG pciData
, // optional
50 IN ULONG DeviceNumber
,
51 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
54 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
55 ULONG slotNumber
= deviceExtension
->slotNumber
;
56 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
57 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
58 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
59 ULONG RevID
= deviceExtension
->RevID
;
60 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
61 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
63 KdPrint2((PRINT_PREFIX
"UniataChipDetectChannels:\n" ));
65 case ATA_ACER_LABS_ID
:
66 switch(deviceExtension
->DevID
) {
69 deviceExtension
->NumberChannels
= 4;
70 KdPrint2((PRINT_PREFIX
"Acer 4 chan\n"));
75 if(ChipType
!= PRMIO
) {
78 deviceExtension
->NumberChannels
= 4;
79 KdPrint2((PRINT_PREFIX
"Promise 4 chan\n"));
82 KdPrint2((PRINT_PREFIX
"Marvell\n"));
83 switch(deviceExtension
->DevID
) {
85 /* 88SX6101 only have 1 PATA channel */
86 if(BMList
[deviceExtension
->DevIndex
].channel
) {
87 KdPrint2((PRINT_PREFIX
"88SX6101 has no 2nd PATA chan\n"));
90 deviceExtension
->NumberChannels
= 1;
91 KdPrint2((PRINT_PREFIX
"88SX6101 PATA 1 chan\n"));
96 KdPrint2((PRINT_PREFIX
"ATI\n"));
97 switch(deviceExtension
->DevID
) {
100 /* IXP600 & IXP700 only have 1 PATA channel */
101 if(BMList
[deviceExtension
->DevIndex
].channel
) {
102 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
105 deviceExtension
->NumberChannels
= 1;
106 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
109 case ATA_SILICON_IMAGE_ID
:
111 if(ChipFlags
& SIIBUG
) {
113 if(ChipType
!= SIIMIO
) {
120 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
121 KdPrint2((PRINT_PREFIX
"New SII\n"));
123 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
125 if(deviceExtension
->HwFlags
& SII4CH
) {
126 deviceExtension
->NumberChannels
= 4;
127 KdPrint2((PRINT_PREFIX
"4 chan\n"));
131 if((deviceExtension
->DevID
== 0x32491106) &&
132 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo
->AccessRanges
)[5].RangeStart
)) {
133 deviceExtension
->NumberChannels
= 3;
134 KdPrint2((PRINT_PREFIX
"VIA 3 chan\n"));
137 } // end switch(VendorID)
140 } // end UniataChipDetectChannels()
144 IN PVOID HwDeviceExtension
,
145 IN PPCI_COMMON_CONFIG pciData
, // optional
146 IN ULONG DeviceNumber
,
147 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
148 IN BOOLEAN
* simplexOnly
151 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
152 ULONG slotNumber
= deviceExtension
->slotNumber
;
153 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
154 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
155 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
156 ULONG RevID
= deviceExtension
->RevID
;
158 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
164 ULONG BaseMemAddress
;
165 ULONG BaseIoAddress1
;
166 ULONG BaseIoAddress2
;
167 ULONG BaseIoAddressBM
;
168 BOOLEAN MemIo
= FALSE
;
170 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
171 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
173 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
175 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
181 BaseIoAddressBM
= pciData
->u
.type0
.BaseAddresses
[4] & ~0x07;
182 deviceExtension
->MaxTransferMode
= BaseIoAddressBM
? ATA_DMA
: ATA_PIO4
;
183 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
184 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
186 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
187 if(i
!= BMLIST_TERMINATOR
) {
188 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
190 KdPrint2((PRINT_PREFIX
" unknown dev, BM addr %#x", BaseIoAddressBM
));
192 KdPrint2((PRINT_PREFIX
" MaxTransferMode %#x\n", deviceExtension
->MaxTransferMode
));
194 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
197 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
204 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
205 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
206 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
207 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
208 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
209 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
210 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
211 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
213 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
214 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
215 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
216 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
218 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
219 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),
220 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
221 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
222 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
223 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
224 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
225 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
227 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
228 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
229 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
231 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
232 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
234 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
235 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
236 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
237 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
238 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
239 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
242 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
243 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
244 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
245 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
246 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
247 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
248 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
249 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
250 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
251 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
252 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
253 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
254 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
255 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| VIAAST
),
256 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| VIAAST
),
257 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| VIAAST
),
258 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6
, "VIA 8237A" , VIA133
| VIAAST
),
259 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8251" , VIA133
| VIAAST
),
260 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
263 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
264 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH
),
265 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH
),
266 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH
),
267 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH
),
268 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
271 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
276 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
277 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
278 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
279 if(i
!= BMLIST_TERMINATOR
) {
280 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
285 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
286 // New chips have own DeviceId
287 if(deviceExtension
->DevID
!= ATA_VIA82C571
)
289 // Old chips have same DeviceId, we can distinguish between them
290 // only by SouthBridge DeviceId
291 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
292 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, slotNumber
, NULL
);
293 if(i
!= BMLIST_TERMINATOR
) {
294 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
295 deviceExtension
->HwFlags
|= VIASOUTH
;
297 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
298 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, slotNumber
, NULL
);
299 if(i
!= BMLIST_TERMINATOR
) {
300 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
310 KdPrint2((PRINT_PREFIX
"Default\n"));
312 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
313 /* do extra chipset specific setups */
314 switch(deviceExtension
->DevID
) {
316 //case ATA_CYPRESS_ID:
317 case 0xc6931080: /* 82c693 ATA controller */
318 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
321 case 0x000116ca: /* Cenatek Rocket Drive controller */
322 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
325 /* case ATA_CYRIX_ID:
326 DevTypeInfo = &CyrixAdapters[0];
328 case 0x01021078: /* Cyrix 5530 ATA33 controller */
329 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
332 case 0x06401039: /* CMD 640 known bad, no DMA */
338 case 0x10001042: /* RZ 100x known bad, no DMA */
341 if(deviceExtension
->BaseIoAddressBM_0
)
342 ScsiPortFreeDeviceBase(HwDeviceExtension
,
343 deviceExtension
->BaseIoAddressBM_0
);
345 deviceExtension
->BaseIoAddressBM_0
= 0;
346 deviceExtension
->BusMaster
= FALSE
;
347 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
350 case 0x81721283: /* IT8172 IDE controller */
351 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
362 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
364 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
365 if(i
== BMLIST_TERMINATOR
) {
368 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
369 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
371 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
373 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
374 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
375 deviceExtension
->HwFlags
= tmp32
;
377 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
378 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
379 deviceExtension
->HwFlags
|= tmp32
;
381 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
382 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
383 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
387 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
388 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
389 if(tmp32
!= 0xffffffff) {
390 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
391 deviceExtension
->MaxTransferMode
= tmp32
;
394 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
395 deviceExtension
->HwFlags
|= UNIATA_SATA
;
398 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
399 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
401 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
402 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
404 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
407 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
412 case ATA_ACER_LABS_ID
:
413 if(ChipFlags
& UNIATA_SATA
) {
414 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
415 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
417 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
419 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
420 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
421 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
422 ULONG unit01
= (c
& 1);
423 ULONG unit10
= (c
& 2);
424 chan
= &deviceExtension
->chan
[c
];
426 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
427 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
429 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
430 UniataInitSyncBaseIO(chan
);
432 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
433 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
436 // SATA not supported yet
438 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
439 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
440 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
442 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
447 if(ChipFlags
& UNIATA_SATA
) {
448 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
449 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
450 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
451 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
452 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
453 KdPrint2((PRINT_PREFIX
"MemIo\n"));
456 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
457 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
458 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
459 chan
= &deviceExtension
->chan
[c
];
461 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
462 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
463 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
464 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
465 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
466 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
468 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
474 if(ChipType
!= PRMIO
) {
480 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
481 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
483 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
484 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
485 KdPrint2((PRINT_PREFIX
"MemIo\n"));
488 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
489 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
490 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
494 chan
= &deviceExtension
->chan
[c
];
499 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
500 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs12
;
501 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
503 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
504 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
506 UniataInitSyncBaseIO(chan
);
508 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
509 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
510 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
511 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
512 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
513 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
518 KdPrint2((PRINT_PREFIX
"ATI\n"));
519 case ATA_SILICON_IMAGE_ID
: {
521 if(ChipFlags
& SIIBUG
) {
523 if(ChipType
!= SIIMIO
) {
530 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
531 KdPrint2((PRINT_PREFIX
"New SII\n"));
533 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
535 //if(deviceExtension->HwFlags & SII4CH) {
536 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
538 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
540 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
541 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
542 KdPrint2((PRINT_PREFIX
"MemIo\n"));
545 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
546 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
548 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
549 ULONG unit01
= (c
& 1);
550 ULONG unit10
= (c
& 2);
552 chan
= &deviceExtension
->chan
[c
];
554 if(deviceExtension
->AltRegMap
) {
555 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
556 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
557 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
559 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
560 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
561 UniataInitSyncBaseIO(chan
);
563 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
564 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
565 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
566 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
567 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
568 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
569 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
570 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
571 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
572 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
573 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
574 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
577 if(ChipFlags
& UNIATA_SATA
) {
578 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
579 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
580 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
581 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
582 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
583 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
585 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
590 case ATA_SERVERWORKS_ID
: {
592 if(ChipType
!= SWKSMIO
) {
599 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
601 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
602 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
604 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
605 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
606 KdPrint2((PRINT_PREFIX
"MemIo\n"));
609 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
610 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
612 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
613 ULONG offs
= c
*0x100;
615 chan
= &deviceExtension
->chan
[c
];
616 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
617 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
618 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
620 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
621 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
622 UniataInitSyncBaseIO(chan
);
624 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
625 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
626 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
627 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
628 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
629 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
631 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
632 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
633 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
634 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
635 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
636 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
638 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
643 //if(ChipType != SIS_SOUTH) {
644 BOOLEAN SIS_182
=FALSE
;
646 if(!(ChipFlags
& SIS_BASE
)) {
647 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
648 //PrintNtConsole("Found SIS_SOUTH\n");
651 // Make some additional checks
652 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
653 ChangePciConfig1(0x57, (a
& 0x7f));
654 GetPciConfig4(0x00, tmp32
);
655 if(tmp32
== ATA_SIS5518
) {
656 ChipType
= SIS133NEW
;
657 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
658 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
659 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
660 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
662 ChangePciConfig1(0x57, (a
| 0x80));
664 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
665 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
666 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
667 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, -1, NULL
, -1 )
670 GetPciConfig1(0x4a, tmp8
);
671 ChangePciConfig1(0x4a, (a
| 0x10));
672 if(tmp32
== ATA_SIS5513
||
673 tmp32
== ATA_SIS5517
) {
674 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
675 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
676 if(i
!= BMLIST_TERMINATOR
) {
677 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
678 //deviceExtension->MaxTransferMode = ATA_UDMA6;
679 deviceExtension
->MaxTransferMode
= SiSSouthAdapters
[i
].MaxTransferMode
;
680 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
681 deviceExtension
->HwFlags
|= UNIATA_SATA
;
682 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182) {
687 // SiS-South not found
688 if(tmp32
== ATA_SIS5517
) {
689 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
690 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
693 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
698 SetPciConfig1(0x4a, tmp8
);
699 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
700 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
701 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
702 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
704 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
706 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
707 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
708 KdPrint2((PRINT_PREFIX
"MemIo\n"));
711 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
712 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
714 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
715 ULONG offs
= c
<< (SIS_182
? 5 : 6);
717 chan
= &deviceExtension
->chan
[c
];
718 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
719 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
720 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
721 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
722 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
723 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
725 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
729 //ChangePciConfig1(0x57, (a | 0x80));
734 if(ChipFlags
& UNIATA_SATA
) {
737 ULONG BaseMemAddress
= 0;
740 case 0x3149: // VIA 6420
741 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
744 case 0x3249: // VIA 6421
745 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
750 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
751 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
752 5, 0, IoSize
* deviceExtension
->NumberChannels
);
753 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
754 KdPrint2((PRINT_PREFIX
"MemIo\n"));
757 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
758 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
760 if(/*deviceExtension->*/BaseMemAddress
) {
761 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
762 if(ChipFlags
& VIABAR
) {
764 ULONG BaseIoAddressBM_0
;
767 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
768 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
769 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
770 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
771 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
772 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
774 chan
= &deviceExtension
->chan
[c
];
776 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, 0x80);
778 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
779 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
781 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2 + FIELD_OFFSET(IDE_REGISTERS_2
, AltStatus
);
782 UniataInitSyncBaseIO(chan
);
784 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
785 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
788 // Do not setup SATA registers for PATA part
789 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
790 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
791 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
792 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
793 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
794 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
796 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
806 if(!(ChipFlags
& UNIATA_SATA
)) {
810 /* the intel 31244 needs special care if in DPA mode */
811 if(DeviceID
== 3200 && // Intel 31244
812 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
814 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
815 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
817 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
818 KdPrint2((PRINT_PREFIX
"MemIo\n"));
821 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
822 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
823 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
825 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
826 ULONG offs
= 0x200 + c
*0x200;
828 chan
= &deviceExtension
->chan
[c
];
829 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
830 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
831 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
834 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
835 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
836 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
837 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
838 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
839 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
840 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
841 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
843 UniataInitSyncBaseIO(chan
);
845 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
846 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
847 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
849 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
850 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
852 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
853 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
854 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
855 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
856 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
857 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
859 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
860 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
861 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
862 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
863 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
864 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
866 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
871 /* SATA parts can be either compat or AHCI */
872 if(ChipFlags
& UNIATA_AHCI
) {
874 GetPciConfig1(0x90, tmp8
);
876 KdPrint2((PRINT_PREFIX
"AHCI not supported yet\n"));
879 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
882 if(ChipFlags
& UNIATA_SATA
) {
883 //BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
885 BaseMemAddress
= NULL
; // HACK-HACK
886 if(!BaseMemAddress
) {
887 KdPrint2((PRINT_PREFIX
"Intel: no SATA I/O space, operate in PATA Compatible mode\n"));
888 deviceExtension
->HwFlags
&= ~UNIATA_SATA
;
891 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
892 KdPrint2((PRINT_PREFIX
"MemIo\n"));
895 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
896 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
901 /* Cyrix 5530 ATA33 controller */
902 if(deviceExtension
->DevID
== 0x01021078) {
903 ConfigInfo
->AlignmentMask
= 0x0f;
904 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
911 } // end UniataChipDetect()
915 Do some 'magic staff' for VIA SouthBridge
916 This will prevent data losses
919 AtapiViaSouthBridgeFixup(
920 IN PVOID HwDeviceExtension
,
921 IN BUS_DATA_TYPE BusDataType
,
922 IN ULONG SystemIoBusNumber
,
926 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
927 PCI_COMMON_CONFIG pciData
;
933 PCI_SLOT_NUMBER slotData
;
935 BOOLEAN found
= FALSE
;
937 slotData
.u
.AsULONG
= slotNumber
;
938 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
940 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
942 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
947 PCI_COMMON_HDR_LENGTH
);
949 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
953 VendorID
= pciData
.VendorID
;
954 DeviceID
= pciData
.DeviceID
;
955 dev_id
= (VendorID
| (DeviceID
<< 16));
957 if (dev_id
== 0x03051106 || /* VIA VT8363 */
958 dev_id
== 0x03911106 || /* VIA VT8371 */
959 dev_id
== 0x31021106 || /* VIA VT8662 */
960 dev_id
== 0x31121106) { /* VIA VT8361 */
963 GetPciConfig1(0x76, reg76
);
965 if ((reg76
& 0xf0) != 0xd0) {
966 SetPciConfig1(0x75, 0x80);
967 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
974 deviceExtension
->HwFlags
&= ~VIABUG
;
976 } // end AtapiViaSouthBridgeFixup()
979 Do some 'magic staff' for ROSB SouthBridge
980 This will prevent data losses
983 AtapiRosbSouthBridgeFixup(
984 IN PVOID HwDeviceExtension
,
985 IN BUS_DATA_TYPE BusDataType
,
986 IN ULONG SystemIoBusNumber
,
990 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
991 PCI_COMMON_CONFIG pciData
;
997 PCI_SLOT_NUMBER slotData
;
999 // BOOLEAN found = FALSE;
1001 /* locate the ISA part in the southbridge and enable UDMA33 */
1002 slotData
.u
.AsULONG
= slotNumber
;
1003 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1005 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1007 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1012 PCI_COMMON_HDR_LENGTH
);
1014 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1018 VendorID
= pciData
.VendorID
;
1019 DeviceID
= pciData
.DeviceID
;
1020 dev_id
= (VendorID
| (DeviceID
<< 16));
1022 if (dev_id
== ATA_ROSB4_ISA
) { /* VIA VT8361 */
1023 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1027 } // end AtapiRosbSouthBridgeFixup()
1030 Do some 'magic staff' for ROSB SouthBridge
1031 This will prevent data losses
1034 AtapiAliSouthBridgeFixup(
1035 IN PVOID HwDeviceExtension
,
1036 IN BUS_DATA_TYPE BusDataType
,
1037 IN ULONG SystemIoBusNumber
,
1038 IN ULONG slotNumber
,
1042 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1043 PCI_COMMON_CONFIG pciData
;
1049 PCI_SLOT_NUMBER slotData
;
1051 // BOOLEAN found = FALSE;
1053 /* workaround for datacorruption bug found on at least SUN Blade-100
1054 * find the ISA function on the southbridge and disable then enable
1055 * the ATA channel tristate buffer */
1056 slotData
.u
.AsULONG
= slotNumber
;
1057 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1059 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1061 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1066 PCI_COMMON_HDR_LENGTH
);
1068 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1072 VendorID
= pciData
.VendorID
;
1073 DeviceID
= pciData
.DeviceID
;
1074 dev_id
= (VendorID
| (DeviceID
<< 16));
1076 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1077 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1078 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1082 } // end AtapiRosbSouthBridgeFixup()
1086 IN PHW_DEVICE_EXTENSION deviceExtension
,
1087 IN ULONG channel
// physical channel number (0-1)
1090 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1091 ULONG slotNumber
= deviceExtension
->slotNumber
;
1092 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1094 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1096 UCHAR reg
, val
, res
;
1097 PCI_SLOT_NUMBER slotData
;
1099 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1101 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1102 reg
= channel
? 0x57 : 0x53;
1103 GetPciConfig1(reg
, val
);
1104 SetPciConfig1(reg
, val
| 0x80);
1108 GetPciConfig1(reg
, val
);
1109 SetPciConfig1(reg
, val
& 0xfe);
1111 GetPciConfig1(0x5a, res
);
1112 res
= res
& (channel
? 0x01 : 0x02);
1113 SetPciConfig1(reg
, val
);
1115 } // end hpt_cable80()
1120 IN PHW_DEVICE_EXTENSION deviceExtension
,
1121 IN ULONG channel
// physical channel number (0-1)
1124 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1125 ULONG slotNumber
= deviceExtension
->slotNumber
;
1126 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1128 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1135 GetPciConfig1(0x50, reg50
);
1152 for (j
=0; j
>=2; i
-= 8) {
1153 i
= (3-(channel
*2+j
))*8;
1154 if (((reg50
>> (i
& 0x10)) & 8) &&
1155 ((reg50
>> i
) & 0x20) &&
1156 (((reg50
>> i
) & 7) < a
)) {
1158 res
|= TRUE
; //(1 << (1 - (i >> 4)));
1163 } // end via_cable80()
1167 IN PHW_DEVICE_EXTENSION deviceExtension
,
1168 IN ULONG channel
, // physical channel number (0-1)
1173 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1174 ULONG slotNumber
= deviceExtension
->slotNumber
;
1175 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1177 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1179 ULONG c
; // logical channel (for Compatible Mode controllers)
1182 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1183 chan
= &deviceExtension
->chan
[c
];
1185 GetPciConfig1(pci_reg
, tmp8
);
1186 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1187 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1192 } // end generic_cable80()
1195 UniAtaReadLunConfig(
1196 IN PHW_DEVICE_EXTENSION deviceExtension
,
1197 IN ULONG channel
, // physical channel
1203 PHW_LU_EXTENSION LunExt
;
1206 c
= channel
- deviceExtension
->Channel
; // logical channel
1208 chan
= &deviceExtension
->chan
[c
];
1210 LunExt
= &(deviceExtension
->lun
[c
*2+ldev
]);
1212 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"ReadCacheEnable", 1);
1213 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1215 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"WriteCacheEnable", 1);
1216 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1218 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1219 LunExt
->opt_MaxTransferMode
= tmp32
;
1221 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"PreferedTransferMode", 0xffffffff);
1222 LunExt
->opt_PreferedTransferMode
= tmp32
;
1224 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"ReadOnly", 0);
1226 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1229 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"GeomType", 0xffffffff);
1233 LunExt
->opt_GeomType
= tmp32
;
1235 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, ldev
, L
"Hidden", 0);
1237 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1241 } // end UniAtaReadLunConfig()
1244 AtapiReadChipConfig(
1245 IN PVOID HwDeviceExtension
,
1246 IN ULONG DeviceNumber
,
1247 IN ULONG channel
// physical channel
1250 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1253 ULONG c
; // logical channel (for Compatible Mode controllers)
1255 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1256 ASSERT(deviceExtension
);
1258 if(channel
!= CHAN_NOT_SPECIFIED
) {
1259 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1261 c
= CHAN_NOT_SPECIFIED
;
1264 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1266 if(channel
== CHAN_NOT_SPECIFIED
) {
1267 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1268 deviceExtension
->simplexOnly
= TRUE
;
1270 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1271 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1272 deviceExtension
->opt_AtapiDmaRawRead
= TRUE
;
1273 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1276 if(c
== CHAN_NOT_SPECIFIED
) {
1277 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1278 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1279 chan
= &deviceExtension
->chan
[c
];
1280 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1281 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1282 if(tmp32
!= 0xffffffff) {
1283 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1284 chan
->MaxTransferMode
= tmp32
;
1286 //UniAtaReadLunConfig(deviceExtension, c, 0);
1287 //UniAtaReadLunConfig(deviceExtension, c, 1);
1290 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1291 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1294 deviceExtension
->opt_AtapiDmaControlCmd
=
1295 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1298 deviceExtension
->opt_AtapiDmaRawRead
=
1299 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1302 deviceExtension
->opt_AtapiDmaReadWrite
=
1303 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1307 chan
= &deviceExtension
->chan
[c
];
1308 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1309 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1310 if(tmp32
!= 0xffffffff) {
1311 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1312 chan
->MaxTransferMode
= tmp32
;
1314 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1315 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1317 UniAtaReadLunConfig(deviceExtension
, channel
, 0);
1318 UniAtaReadLunConfig(deviceExtension
, channel
, 1);
1322 } // end AtapiReadChipConfig()
1326 IN PVOID HwDeviceExtension
,
1327 IN ULONG DeviceNumber
,
1328 IN ULONG channel
// physical channel
1331 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1332 ULONG slotNumber
= deviceExtension
->slotNumber
;
1333 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1334 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1335 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1336 ULONG RevID
= deviceExtension
->RevID
;
1338 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1339 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1340 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1345 ULONG c
; // logical channel (for Compatible Mode controllers)
1346 BOOLEAN CheckCable
= FALSE
;
1347 //ULONG BaseIoAddress;
1350 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1353 case CHAN_NOT_SPECIFIED
:
1354 c
= CHAN_NOT_SPECIFIED
;
1357 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1360 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1362 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1363 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1365 if(deviceExtension
->UnknownDev
) {
1366 KdPrint2((PRINT_PREFIX
" Unknown chip, exiting\n" ));
1368 VendorID
= 0xffffffff;
1372 // case ATA_ACARD_ID:
1374 case ATA_ACER_LABS_ID
:
1375 if(ChipFlags
& UNIATA_SATA
) {
1376 if(c
== CHAN_NOT_SPECIFIED
) {
1377 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1378 chan
= &deviceExtension
->chan
[c
];
1379 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1380 /* the southbridge might need the data corruption fix */
1381 if(RevID
== 0xc2 || RevID
== 0xc3) {
1382 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1383 SystemIoBusNumber
, slotNumber
, c
);
1386 /* enable PCI interrupt */
1387 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1390 if(ChipFlags
& ALINEW
) {
1391 if(c
== CHAN_NOT_SPECIFIED
) {
1392 /* use device interrupt as byte count end */
1393 ChangePciConfig1(0x4a, (a
| 0x20));
1394 /* enable cable detection and UDMA support on newer chips */
1395 ChangePciConfig1(0x4b, (a
| 0x09));
1397 /* enable ATAPI UDMA mode */
1398 ChangePciConfig1(0x53, (a
| 0x01));
1401 // check 80-pin cable
1402 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
1405 if(c
== CHAN_NOT_SPECIFIED
) {
1406 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1407 ChangePciConfig1(0x53, (a
| 0x03));
1410 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1415 if(c
== CHAN_NOT_SPECIFIED
) {
1416 /* set prefetch, postwrite */
1417 if(ChipFlags
& AMDBUG
) {
1418 ChangePciConfig1(0x41, (a
& 0x0f));
1420 ChangePciConfig1(0x41, (a
| 0xf0));
1423 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1425 // check 80-pin cable
1426 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
1427 if(c
== CHAN_NOT_SPECIFIED
) {
1430 generic_cable80(deviceExtension
, channel
, 0x42, 0);
1434 case ATA_HIGHPOINT_ID
:
1436 if(c
== CHAN_NOT_SPECIFIED
) {
1438 if(ChipFlags
& HPTOLD
) {
1439 /* turn off interrupt prediction */
1440 ChangePciConfig1(0x51, (a
& ~0x80));
1442 /* turn off interrupt prediction */
1443 ChangePciConfig1(0x51, (a
& ~0x03));
1444 ChangePciConfig1(0x55, (a
& ~0x03));
1445 /* turn on interrupts */
1446 ChangePciConfig1(0x5a, (a
& ~0x10));
1447 /* set clocks etc */
1448 if(ChipType
< HPT372
) {
1449 SetPciConfig1(0x5b, 0x22);
1451 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
1456 // check 80-pin cable
1457 chan
= &deviceExtension
->chan
[c
];
1458 if(!hpt_cable80(deviceExtension
, channel
)) {
1459 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1463 case ATA_INTEL_ID
: {
1465 if(ChipFlags
& UNIATA_SATA
) {
1466 if(c
!= CHAN_NOT_SPECIFIED
)
1469 /* force all ports active "the legacy way" */
1470 ChangePciConfig2(0x92, (a
| 0x0f));
1471 /* enable PCI interrupt */
1472 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1474 if(!(ChipFlags
& UNIATA_AHCI
)) {
1475 /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
1476 GetPciConfig1(0x90, tmp8
);
1477 if(!(tmp8
& 0x04)) {
1478 /* XXX SOS should be in intel_allocate if we grow it */
1479 if(c
== CHAN_NOT_SPECIFIED
) {
1480 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1481 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1484 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1489 /* enable PCI interrupt */
1490 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1494 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1496 // check 80-pin cable
1497 if(c
== CHAN_NOT_SPECIFIED
) {
1500 chan
= &deviceExtension
->chan
[c
];
1501 GetPciConfig2(0x54, reg54
);
1502 if( ((reg54
>> (channel
*2)) & 30) != 30) {
1503 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1507 case ATA_NVIDIA_ID
: {
1508 if(ChipFlags
& UNIATA_SATA
) {
1509 if(c
== CHAN_NOT_SPECIFIED
) {
1510 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
1511 /* enable control access */
1512 ChangePciConfig1(0x50, (a
| 0x04));
1513 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
1514 if(ChipFlags
& NVQ
) {
1515 /* clear interrupt status */
1516 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
1517 /* enable device and PHY state change interrupts */
1518 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
1519 /* disable NCQ support */
1520 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
1521 AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
1523 /* clear interrupt status */
1524 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
1525 /* enable device and PHY state change interrupts */
1526 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
1528 /* enable PCI interrupt */
1529 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1531 //UniataSataPhyEnable(HwDeviceExtension, c);
1536 if(c
== CHAN_NOT_SPECIFIED
) {
1537 /* set prefetch, postwrite */
1538 ChangePciConfig1(0x51, (a
& 0x0f));
1540 // check 80-pin cable
1541 generic_cable80(deviceExtension
, channel
, 0x52, 1);
1542 /* chan = &deviceExtension->chan[c];
1543 GetPciConfig1(0x52, reg52);
1544 if( !((reg52 >> (channel*2)) & 0x01)) {
1545 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1550 case ATA_PROMISE_ID
: {
1555 if(c
== CHAN_NOT_SPECIFIED
) {
1556 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
1557 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
1558 AtapiReadPortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
1562 /* enable burst mode */
1563 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
1564 if(c
== CHAN_NOT_SPECIFIED
) {
1565 AtapiWritePortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
1566 AtapiReadPortEx1(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
1568 // check 80-pin cable
1569 chan
= &deviceExtension
->chan
[c
];
1570 GetPciConfig2(0x50, Reg50
);
1571 if(Reg50
& (1 << (channel
+10))) {
1572 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1577 if(c
== CHAN_NOT_SPECIFIED
) {
1580 // check 80-pin cable
1581 chan
= &deviceExtension
->chan
[c
];
1582 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
1583 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
1584 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1589 if(c
== CHAN_NOT_SPECIFIED
) {
1590 if(ChipFlags
& PRSATA
) {
1591 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressBM_0
),0x6c, 0x000000ff);
1594 chan
= &deviceExtension
->chan
[c
];
1595 AtapiWritePort4(chan
, IDX_BM_Command
,
1596 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
1597 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
1598 // check 80-pin cable
1599 if(chan
->MaxTransferMode
< ATA_SA150
&&
1600 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
1601 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1607 case ATA_SERVERWORKS_ID
:
1608 if(c
== CHAN_NOT_SPECIFIED
) {
1609 if(ChipType
== SWKS33
) {
1610 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1611 SystemIoBusNumber
, slotNumber
);
1613 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
1618 if(ChipType
== SIIMIO
) {
1619 KdPrint2((PRINT_PREFIX
"ATI New\n"));
1622 KdPrint2((PRINT_PREFIX
"ATI\n"));
1625 case ATA_SILICON_IMAGE_ID
:
1626 /* if(ChipFlags & SIIENINTR) {
1627 SetPciConfig1(0x71, 0x01);
1632 KdPrint2((PRINT_PREFIX
"SII\n"));
1635 if(c
== CHAN_NOT_SPECIFIED
) {
1636 if(ChipFlags
& SIISETCLK
) {
1637 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
1638 GetPciConfig1(0x8a, tmp8
);
1639 if ((tmp8
& 0x30) != 0x10)
1640 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
1641 GetPciConfig1(0x8a, tmp8
);
1642 if ((tmp8
& 0x30) != 0x10) {
1643 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
1644 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1648 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
1649 // check 80-pin cable
1650 if(c
== CHAN_NOT_SPECIFIED
) {
1653 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
1654 chan
= &deviceExtension
->chan
[c
];
1655 GetPciConfig2(0x79, Reg79
);
1656 if(Reg79
& (channel
? 0x02 : 0x01)) {
1657 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1661 ULONG unit01
= (c
& 1);
1662 ULONG unit10
= (c
& 2);
1663 /* enable/disable PHY state change interrupt */
1664 if(c
== CHAN_NOT_SPECIFIED
) {
1665 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1668 if(ChipFlags
& SIINOSATAIRQ
) {
1669 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
1670 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
1674 if(ChipFlags
& SIINOSATAIRQ
) {
1675 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
1676 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
1678 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
1679 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
1683 if(c
== CHAN_NOT_SPECIFIED
) {
1684 /* enable interrupt as BIOS might not */
1685 ChangePciConfig1(0x8a, (a
& 0x3f));
1686 // Enable 3rd and 4th channels
1687 if (ChipFlags
& SII4CH
) {
1688 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
1689 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
1692 chan
= &deviceExtension
->chan
[c
];
1693 /* dont block interrupts */
1694 //ChangePciConfig4(0x48, (a & ~0x03c00000));
1695 tmp32
= AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
1696 AtapiWritePortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
1698 tmp32
= AtapiReadPortEx4(NULL
, (ULONG
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
1700 /* Initialize FIFO PCI bus arbitration */
1701 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
1703 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp32
));
1705 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
1707 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
1714 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
1715 if(c
== CHAN_NOT_SPECIFIED
) {
1716 /* Setup interrupts. */
1717 SetPciConfig1(0x71, 0x01);
1719 /* GetPciConfig1(0x8a, tmp8);
1721 SetPciConfig1(0x71, tmp8);*/
1723 /* Use MEMORY READ LINE for reads.
1724 * NOTE: Although not mentioned in the PCI0646U specs,
1725 * these bits are write only and won't be read
1726 * back as set or not. The PCI0646U2 specs clarify
1730 SetPciConfig1(0x71, tmp8);
1732 /* Set reasonable active/recovery/address-setup values. */
1733 SetPciConfig1(0x53, 0x40);
1734 SetPciConfig1(0x54, 0x3f);
1735 SetPciConfig1(0x55, 0x40);
1736 SetPciConfig1(0x56, 0x3f);
1737 SetPciConfig1(0x57, 0x1c);
1738 SetPciConfig1(0x58, 0x3f);
1739 SetPciConfig1(0x5b, 0x3f);
1746 if(c
== CHAN_NOT_SPECIFIED
) {
1752 ChangePciConfig1(0x52, (a
& ~0x04));
1756 ChangePciConfig1(0x49, (a
& ~0x01));
1759 ChangePciConfig2(0x50, (a
| 0x0008));
1760 ChangePciConfig2(0x52, (a
| 0x0008));
1763 ChangePciConfig2(0x04, (a
& ~0x0400));
1766 if(ChipType
== SIS133NEW
) {
1768 // check 80-pin cable
1769 if(c
== CHAN_NOT_SPECIFIED
) {
1772 chan
= &deviceExtension
->chan
[c
];
1773 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
1774 if(tmp16
& 0x8000) {
1775 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1779 // check 80-pin cable
1780 if(c
== CHAN_NOT_SPECIFIED
) {
1783 chan
= &deviceExtension
->chan
[c
];
1784 GetPciConfig1(48, tmp8
);
1785 if(tmp8
& (0x10 << channel
)) {
1786 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1793 if(c
== CHAN_NOT_SPECIFIED
) {
1794 /* prepare for ATA-66 on the 82C686a and 82C596b */
1795 if(ChipFlags
& VIACLK
) {
1796 ChangePciConfig4(0x50, (a
| 0x030b030b));
1799 if(ChipFlags
& UNIATA_SATA
) {
1800 /* enable PCI interrupt */
1801 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1805 /* the southbridge might need the data corruption fix */
1806 if(ChipFlags
& VIABUG
) {
1807 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1808 SystemIoBusNumber
, slotNumber
);
1810 /* set prefetch, postwrite */
1811 if(ChipType
!= VIA133
) {
1812 ChangePciConfig1(0x41, (a
| 0xf0));
1815 /* set fifo configuration half'n'half */
1816 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
1818 /* set status register read retry */
1819 ChangePciConfig1(0x44, (a
| 0x08));
1821 /* set DMA read & end-of-sector fifo flush */
1822 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
1824 /* set sector size */
1825 SetPciConfig2(0x60, DEV_BSIZE
);
1826 SetPciConfig2(0x68, DEV_BSIZE
);
1828 // check 80-pin cable
1829 chan
= &deviceExtension
->chan
[c
];
1830 if(!via_cable80(deviceExtension
, channel
)) {
1831 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1839 if(ChipType
== ITE_33
)
1841 if(c
== CHAN_NOT_SPECIFIED
) {
1842 /* set PCI mode and 66Mhz reference clock */
1843 ChangePciConfig1(0x50, a
& ~0x83);
1845 /* set default active & recover timings */
1846 SetPciConfig1(0x54, 0x31);
1847 SetPciConfig1(0x56, 0x31);
1849 // check 80-pin cable
1850 GetPciConfig2(0x40, tmp16
);
1851 chan
= &deviceExtension
->chan
[c
];
1852 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
1853 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1859 if(c
!= CHAN_NOT_SPECIFIED
) {
1860 // We don't know how to check for 80-pin cable on unknown controllers.
1861 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
1862 // So, leave this flag to use as hint in error recovery procedures
1863 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
1864 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
1869 // In all places separate channels are inited after common controller init
1870 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
1871 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
1872 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1873 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
1878 } // end AtapiChipInit()
1882 IN PHW_DEVICE_EXTENSION deviceExtension
,
1883 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
1891 if(!BaseIoAddressBM_0
) {
1894 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1895 chan
= &deviceExtension
->chan
[c
];
1896 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
1897 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONG
)BaseIoAddressBM_0
+ i
) : 0;
1898 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
1900 if(BaseIoAddressBM_0
) {
1901 BaseIoAddressBM_0
++;
1904 } // end UniataInitMapBM()
1908 IN PHW_CHANNEL chan
,
1909 IN PIDE_REGISTERS_1 BaseIoAddress1
,
1910 IN PIDE_REGISTERS_2 BaseIoAddress2
1915 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
1916 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONG
)BaseIoAddress1
+ i
) : 0;
1917 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
1919 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
1920 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONG
)BaseIoAddress2
+ i
) : 0;
1921 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
1923 UniataInitSyncBaseIO(chan
);
1924 } // end UniataInitMapBase()
1927 UniataInitSyncBaseIO(
1931 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
1932 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
1933 } // end UniataInitSyncBaseIO()