3 Copyright (c) 2004-2012 Alexandr A. Telyatnikov (Alter)
9 This is the chip-specific init module for ATA/ATAPI IDE controllers
10 with Busmaster DMA and Serial ATA support
13 Alexander A. Telyatnikov (Alter)
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 Some parts of code were taken from FreeBSD 5.1-6.1 ATA driver by
34 Søren Schmidt, Copyright (c) 1998-2007
35 added IT8172 IDE controller support from Linux
36 added VIA 8233/8235 fix from Linux
37 added 80-pin cable detection from Linux for
39 added support for non-standard layout of registers
48 UniataChipDetectChannels(
49 IN PVOID HwDeviceExtension
,
50 IN PPCI_COMMON_CONFIG pciData
, // optional
51 IN ULONG DeviceNumber
,
52 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
55 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
56 //ULONG slotNumber = deviceExtension->slotNumber;
57 //ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
58 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
59 //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
60 //ULONG RevID = deviceExtension->RevID;
61 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
62 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
64 KdPrint2((PRINT_PREFIX
"UniataChipDetectChannels:\n" ));
66 if(ChipFlags
& (UNIATA_SATA
| UNIATA_AHCI
)) {
67 if(!deviceExtension
->NumberChannels
) {
68 KdPrint2((PRINT_PREFIX
"uninitialized SATA/AHCI port number -> 1\n"));
69 deviceExtension
->NumberChannels
= 1;
71 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"IgnoreAhciPM", 1 /* DEBUG */)) {
72 KdPrint2((PRINT_PREFIX
"SATA/AHCI w/o PM, max luns 1 or 2\n"));
73 deviceExtension
->NumberLuns
= 2; // we may be in Legacy mode
74 //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
76 KdPrint2((PRINT_PREFIX
"SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS
));
77 deviceExtension
->NumberLuns
= SATA_MAX_PM_UNITS
;
78 //deviceExtension->NumberLuns = 1;
81 if(deviceExtension
->MasterDev
) {
82 KdPrint2((PRINT_PREFIX
"MasterDev -> 1 chan\n"));
83 deviceExtension
->NumberChannels
= 1;
87 case ATA_ACER_LABS_ID
:
88 switch(deviceExtension
->DevID
) {
91 deviceExtension
->NumberChannels
= 4;
92 KdPrint2((PRINT_PREFIX
"Acer 4 chan\n"));
97 if(ChipType
!= PRMIO
) {
100 deviceExtension
->NumberChannels
= 4;
101 KdPrint2((PRINT_PREFIX
"Promise 4 chan\n"));
104 KdPrint2((PRINT_PREFIX
"Marvell\n"));
105 switch(deviceExtension
->DevID
) {
107 /* 88SX6101 only have 1 PATA channel */
108 if(BMList
[deviceExtension
->DevIndex
].channel
) {
109 KdPrint2((PRINT_PREFIX
"88SX6101 has no 2nd PATA chan\n"));
112 deviceExtension
->NumberChannels
= 1;
113 KdPrint2((PRINT_PREFIX
"88SX6101 PATA 1 chan\n"));
118 KdPrint2((PRINT_PREFIX
"ATI\n"));
119 switch(deviceExtension
->DevID
) {
122 /* IXP600 & IXP700 only have 1 PATA channel */
123 if(BMList
[deviceExtension
->DevIndex
].channel
) {
124 KdPrint2((PRINT_PREFIX
"New ATI no 2nd PATA chan\n"));
127 deviceExtension
->NumberChannels
= 1;
128 KdPrint2((PRINT_PREFIX
"New ATI PATA 1 chan\n"));
132 case ATA_SILICON_IMAGE_ID
:
134 if(ChipFlags
& SIIBUG
) {
135 /* work around errata in early chips */
136 deviceExtension
->DmaSegmentLength
= 15 * DEV_BSIZE
;
137 deviceExtension
->DmaSegmentAlignmentMask
= 8192-1;
139 if(ChipType
!= SIIMIO
) {
146 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
147 KdPrint2((PRINT_PREFIX
"New SII\n"));
149 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
151 if(deviceExtension
->HwFlags
& SII4CH
) {
152 deviceExtension
->NumberChannels
= 4;
153 KdPrint2((PRINT_PREFIX
"4 chan\n"));
157 if(/*(deviceExtension->DevID == 0x32491106) &&
158 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)*/
159 deviceExtension
->HwFlags
& VIABAR
) {
160 deviceExtension
->NumberChannels
= 3;
161 KdPrint2((PRINT_PREFIX
"VIA 3 chan\n"));
163 if(ChipFlags
& VIASATA
) {
164 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
165 // do nothing, generic PATA INIT
166 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs -> no PM\n"));
167 deviceExtension
->NumberLuns
= 1;
171 /* ITE ATA133 controller */
172 if(deviceExtension
->DevID
== 0x82131283) {
173 if(BMList
[deviceExtension
->DevIndex
].channel
) {
174 KdPrint2((PRINT_PREFIX
"New ITE has no 2nd PATA chan\n"));
177 deviceExtension
->NumberChannels
= 1;
178 KdPrint2((PRINT_PREFIX
"New ITE PATA 1 chan\n"));
182 /* New Intel PATA controllers */
183 if(g_opt_VirtualMachine
!= VM_VBOX
&&
184 /*deviceExtension->DevID == 0x27df8086 ||
185 deviceExtension->DevID == 0x269e8086 ||
186 deviceExtension->DevID == ATA_I82801HBM*/
188 if(BMList
[deviceExtension
->DevIndex
].channel
) {
189 KdPrint2((PRINT_PREFIX
"New Intel PATA has no 2nd chan\n"));
192 deviceExtension
->NumberChannels
= 1;
193 KdPrint2((PRINT_PREFIX
"New Intel PATA 1 chan\n"));
197 /* New JMicron PATA controllers */
198 if(deviceExtension
->DevID
== ATA_JMB361
||
199 deviceExtension
->DevID
== ATA_JMB363
||
200 deviceExtension
->DevID
== ATA_JMB368
) {
201 if(BMList
[deviceExtension
->DevIndex
].channel
) {
202 KdPrint2((PRINT_PREFIX
"New JMicron has no 2nd chan\n"));
205 deviceExtension
->NumberChannels
= 1;
206 KdPrint2((PRINT_PREFIX
"New JMicron PATA 1 chan\n"));
209 } // end switch(VendorID)
212 } // end UniataChipDetectChannels()
217 IN PVOID HwDeviceExtension
,
218 IN PPCI_COMMON_CONFIG pciData
, // optional
219 IN ULONG DeviceNumber
,
220 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
221 IN BOOLEAN
* simplexOnly
224 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
225 ULONG slotNumber
= deviceExtension
->slotNumber
;
226 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
227 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
228 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
229 ULONG RevID
= deviceExtension
->RevID
;
231 BUSMASTER_CONTROLLER_INFORMATION
* DevTypeInfo
;
237 ULONG BaseMemAddress
;
238 ULONG BaseIoAddress1
;
239 ULONG BaseIoAddress2
;
240 ULONG BaseIoAddressBM
;
241 BOOLEAN MemIo
= FALSE
;
243 KdPrint2((PRINT_PREFIX
"UniataChipDetect:\n" ));
244 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
246 i
= Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[0], VendorID
, 0xffff, 0, NUM_BUSMASTER_ADAPTERS
);
248 c
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", 0);
254 BaseIoAddressBM
= pciData
->u
.type0
.BaseAddresses
[4] & ~0x07;
255 deviceExtension
->MaxTransferMode
= BaseIoAddressBM
? ATA_DMA
: ATA_PIO4
;
256 ConfigInfo
->MaximumTransferLength
= DEV_BSIZE
*256;
257 deviceExtension
->MaximumDmaTransferLength
= ConfigInfo
->MaximumTransferLength
;
258 //deviceExtension->NumberOfPhysicalBreaks = min(deviceExtension->MaximumDmaTransferLength/PAGE_SIZE+1, ATA_DMA_ENTRIES);
259 deviceExtension
->DmaSegmentLength
= 0x10000;
260 deviceExtension
->DmaSegmentAlignmentMask
= 0xffff;
262 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
263 if(i
!= BMLIST_TERMINATOR
) {
264 DevTypeInfo
= (PBUSMASTER_CONTROLLER_INFORMATION
)&BusMasterAdapters
[i
];
267 if(Ata_is_ahci_dev(pciData
)) {
268 KdPrint2((PRINT_PREFIX
" AHCI candidate"));
270 deviceExtension
->NumberChannels
= 0;
271 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
272 KdPrint2((PRINT_PREFIX
" AHCI init failed - not detected\n"));
273 return STATUS_UNSUCCESSFUL
;
275 KdPrint2((PRINT_PREFIX
" unknown AHCI dev, addr %#x ", deviceExtension
->BaseIoAHCI_0
.Addr
));
277 KdPrint2((PRINT_PREFIX
" unknown dev, BM addr %#x ", BaseIoAddressBM
));
279 KdPrint2((PRINT_PREFIX
" MaxTransferMode %#x\n", deviceExtension
->MaxTransferMode
));
281 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
282 return STATUS_UNSUCCESSFUL
;
284 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
285 return STATUS_UNSUCCESSFUL
;
287 // DEBUG, we shall return success when AHCI is completly supported
288 //return STATUS_NOT_FOUND;
289 return STATUS_SUCCESS
;
292 static BUSMASTER_CONTROLLER_INFORMATION
const SiSAdapters
[] = {
293 PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150
, "SiS 182" , SISSATA
| UNIATA_SATA
),
294 PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150
, "SiS 181" , SISSATA
| UNIATA_SATA
),
295 PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150
, "SiS 180" , SISSATA
| UNIATA_SATA
),
296 PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6
, "SiS 965" , SIS133NEW
),
297 PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6
, "SiS 964" , SIS133NEW
),
298 PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6
, "SiS 963" , SIS133NEW
),
299 PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6
, "SiS 962" , SIS133NEW
),
301 PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5
, "SiS 745" , SIS100NEW
),
302 PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5
, "SiS 735" , SIS100NEW
),
303 PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5
, "SiS 733" , SIS100NEW
),
304 PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5
, "SiS 730" , SIS100OLD
),
306 PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6
, "SiS 645DX", SIS133NEW
),
307 /* PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS133NEW ),*/
308 /* PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),*/
309 PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5
, "SiS 635" , SIS100NEW
),
310 PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5
, "SiS 633" , SIS100NEW
),
311 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5
, "SiS 630S" , SIS100OLD
),
312 PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4
, "SiS 630" , SIS66
),
313 PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4
, "SiS 620" , SIS66
),
315 PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5
, "SiS 550" , SIS66
),
316 PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4
, "SiS 540" , SIS66
),
317 PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4
, "SiS 530" , SIS66
),
319 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD ), // ???
320 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961" , SIS133OLD ),
322 PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5
, "SiS 961" , SIS100NEW
| SIS_BASE
),
323 PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6
, "SiS 962/3", SIS133NEW
| SIS_BASE
),
324 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
325 PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
326 PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2
, "SiS 5513" , SIS33
| SIS_BASE
),
327 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
330 static BUSMASTER_CONTROLLER_INFORMATION
const ViaAdapters
[] = {
331 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
332 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2
, "VIA 82C586B", VIA33
| VIAPRQ
),
333 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2
, "VIA 82C586B", VIA33
| 0x00 ),
334 PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2
, "VIA 82C586" , VIA33
| 0x00 ),
335 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4
, "VIA 82C596B", VIA66
| VIACLK
),
336 PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2
, "VIA 82C596" , VIA33
| 0x00 ),
337 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5
, "VIA 82C686B", VIA100
| VIABUG
),
338 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4
, "VIA 82C686A", VIA66
| VIACLK
),
339 PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2
, "VIA 82C686" , VIA33
| 0x00 ),
340 PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5
, "VIA 8231" , VIA100
| VIABUG
),
341 PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5
, "VIA 8233" , VIA100
| 0x00 ),
342 PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5
, "VIA 8233C" , VIA100
| 0x00 ),
343 PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6
, "VIA 8233A" , VIA133
| 0x00 ),
344 PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6
, "VIA 8235" , VIA133
| 0x00 ),
345 PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
346 PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6
, "VIA 8237A" , VIA133
| 0x00 ),
347 // presence of AHCI controller means something about isa-mapped part
348 PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_UDMA6
, "VIA 8237S" , VIA133
| 0x00 ),
349 PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
350 PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6
, "VIA 8237" , VIA133
| 0x00 ),
351 PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6
, "VIA 8251" , VIA133
| 0x00 ),
352 PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150
, "VIA CX700" , VIA133
| VIASATA
),
353 PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150
, "VIA VX800" , VIA133
| VIASATA
),
354 PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6
, "VIA VX855" , VIA133
| 0x00 ),
355 PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300
, "VIA VX900" , VIA133
| VIASATA
),
356 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
359 static BUSMASTER_CONTROLLER_INFORMATION
const ViaSouthAdapters
[] = {
360 PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH
),
361 PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH
),
362 PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH
),
363 PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH
),
364 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, BMLIST_TERMINATOR
, NULL
, BMLIST_TERMINATOR
)
367 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
372 KdPrint2((PRINT_PREFIX
"ATA_SIS_ID\n"));
373 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&SiSAdapters
[0];
374 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
375 if(i
!= BMLIST_TERMINATOR
) {
376 deviceExtension
->FullDevName
= SiSAdapters
[i
].FullDevName
;
381 KdPrint2((PRINT_PREFIX
"ATA_VIA_ID\n"));
382 // New chips have own DeviceId
383 if(deviceExtension
->DevID
!= ATA_VIA82C571
&&
384 deviceExtension
->DevID
!= ATA_VIACX700IDE
&&
385 deviceExtension
->DevID
!= ATA_VIASATAIDE
&&
386 deviceExtension
->DevID
!= ATA_VIASATAIDE2
&&
387 deviceExtension
->DevID
!= ATA_VIASATAIDE3
) {
388 KdPrint2((PRINT_PREFIX
"Via new\n"));
391 KdPrint2((PRINT_PREFIX
"Via-old-style %x\n", deviceExtension
->DevID
));
392 // Traditionally, chips have same DeviceId, we can distinguish between them
393 // only by ISA Bridge DeviceId
394 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaSouthAdapters
[0];
395 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
396 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
397 /* if(i == BMLIST_TERMINATOR) {
398 i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
400 if(i
!= BMLIST_TERMINATOR
) {
401 KdPrint2((PRINT_PREFIX
"VIASOUTH\n"));
402 deviceExtension
->HwFlags
|= VIASOUTH
;
404 DevTypeInfo
= (BUSMASTER_CONTROLLER_INFORMATION
*)&ViaAdapters
[0];
405 i
= AtapiFindListedDev(DevTypeInfo
, -1, HwDeviceExtension
, SystemIoBusNumber
,
406 PCISLOTNUM_NOT_SPECIFIED
/*slotNumber*/, NULL
);
407 if(i
!= BMLIST_TERMINATOR
) {
408 deviceExtension
->FullDevName
= ViaAdapters
[i
].FullDevName
;
418 KdPrint2((PRINT_PREFIX
"Default\n"));
420 deviceExtension
->MaxTransferMode
= deviceExtension
->BaseIoAddressBM_0
? ATA_DMA
: ATA_PIO4
;
421 /* do extra chipset specific setups */
422 switch(deviceExtension
->DevID
) {
424 //case ATA_CYPRESS_ID:
425 case 0xc6931080: /* 82c693 ATA controller */
426 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
429 case 0x000116ca: /* Cenatek Rocket Drive controller */
430 deviceExtension
->MaxTransferMode
= ATA_WDMA2
;
433 /* case ATA_CYRIX_ID:
434 DevTypeInfo = &CyrixAdapters[0];
436 case 0x01021078: /* Cyrix 5530 ATA33 controller */
437 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
440 case 0x06401039: /* CMD 640 known bad, no DMA */
446 case 0x10001042: /* RZ 100x known bad, no DMA */
449 if(deviceExtension
->BaseIoAddressBM_0
)
450 ScsiPortFreeDeviceBase(HwDeviceExtension
,
451 deviceExtension
->BaseIoAddressBM_0
);
453 deviceExtension
->BaseIoAddressBM_0
= 0;
454 deviceExtension
->BusMaster
= DMA_MODE_NONE
;
455 deviceExtension
->MaxTransferMode
= ATA_PIO4
;
458 case 0x81721283: /* IT8172 IDE controller */
459 deviceExtension
->MaxTransferMode
= ATA_UDMA2
;
464 return STATUS_NOT_FOUND
;
466 return STATUS_SUCCESS
;
470 i
= Ata_is_dev_listed(DevTypeInfo
, VendorID
, DeviceID
, RevID
, -1);
472 KdPrint2((PRINT_PREFIX
"i: %#x\n", i
));
473 if(i
== BMLIST_TERMINATOR
) {
475 //return STATUS_NOT_FOUND;
477 deviceExtension
->MaxTransferMode
= DevTypeInfo
[i
].MaxTransferMode
;
478 deviceExtension
->HwFlags
|= DevTypeInfo
[i
].RaidFlags
;
480 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
482 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsOverride", deviceExtension
->HwFlags
);
483 KdPrint2((PRINT_PREFIX
"HwFlagsOverride: %#x\n", tmp32
));
484 deviceExtension
->HwFlags
= tmp32
;
486 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"HwFlagsAdd", 0);
487 KdPrint2((PRINT_PREFIX
"HwFlagsAdd: %#x\n", tmp32
));
488 deviceExtension
->HwFlags
|= tmp32
;
490 KdPrint2((PRINT_PREFIX
"HwFlags (final): %#x\n", deviceExtension
->HwFlags
));
491 if(deviceExtension
->HwFlags
& UNIATA_SIMPLEX_ONLY
) {
492 KdPrint2((PRINT_PREFIX
"UNIATA_SIMPLEX_ONLY\n" ));
496 KdPrint2((PRINT_PREFIX
"MaxTransferMode: %#x\n", deviceExtension
->MaxTransferMode
));
497 tmp32
= AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", deviceExtension
->MaxTransferMode
);
498 if(tmp32
!= 0xffffffff) {
499 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", deviceExtension
->MaxTransferMode
));
500 deviceExtension
->MaxTransferMode
= tmp32
;
503 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
504 deviceExtension
->HwFlags
|= UNIATA_SATA
;
507 ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
508 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
510 ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
511 ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
513 if(ChipFlags
& UNIATA_AHCI
) {
514 deviceExtension
->NumberChannels
= 0;
515 if(!UniataAhciDetect(HwDeviceExtension
, pciData
, ConfigInfo
)) {
516 KdPrint2((PRINT_PREFIX
" AHCI detect failed\n"));
517 return STATUS_UNSUCCESSFUL
;
520 if(!UniataChipDetectChannels(HwDeviceExtension
, pciData
, DeviceNumber
, ConfigInfo
)) {
521 return STATUS_UNSUCCESSFUL
;
523 // UniataAhciDetect() sets proper number of channels
524 if(!UniataAllocateLunExt(deviceExtension
, UNIATA_ALLOCATE_NEW_LUNS
)) {
525 return STATUS_UNSUCCESSFUL
;
528 if(ChipFlags
& UNIATA_AHCI
) {
532 case ATA_ACER_LABS_ID
:
533 if(ChipFlags
& UNIATA_SATA
) {
534 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
535 BaseIoAddress1
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
537 BaseIoAddress2
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
539 BaseIoAddressBM
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
540 4, 0, deviceExtension
->NumberChannels
*sizeof(IDE_BUSMASTER_REGISTERS
));
541 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
542 //ULONG unit01 = (c & 1);
543 ULONG unit10
= (c
& 2);
544 chan
= &deviceExtension
->chan
[c
];
546 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
547 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
+ i
+ (unit10
? 8 : 0);
549 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIoAddress2
+ 2 + (unit10
? 4 : 0);
550 UniataInitSyncBaseIO(chan
);
552 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
553 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM
+ i
+ (c
* sizeof(IDE_BUSMASTER_REGISTERS
));
556 // SATA not supported yet
558 //chan->RegTranslation[IDX_BM_Command] = BaseMemAddress + 0x260 + offs7;
559 //chan->RegTranslation[IDX_BM_PRD_Table] = BaseMemAddress + 0x244 + offs7;
560 //chan->RegTranslation[IDX_BM_DeviceSpecific0] = BaseMemAddress + (c << 2);
562 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
567 if(ChipFlags
& UNIATA_SATA
) {
568 KdPrint2((PRINT_PREFIX
"NVIDIA SATA\n"));
569 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
570 5, 0, ((ChipFlags
& NV4OFF
) ? 0x400 : 0) + 0x40*2);
571 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
572 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
573 KdPrint2((PRINT_PREFIX
"MemIo\n"));
576 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
577 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
578 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
579 chan
= &deviceExtension
->chan
[c
];
581 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
<< 6);
582 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
583 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
<< 6);
584 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
585 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
<< 6);
586 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
588 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
594 if(ChipType
!= PRMIO
) {
600 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
601 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
603 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
604 if((*ConfigInfo
->AccessRanges
)[4].RangeInMemory
) {
605 KdPrint2((PRINT_PREFIX
"MemIo\n"));
608 deviceExtension
->BaseIoAddressBM_0
.Addr
= BaseMemAddress
;
609 deviceExtension
->BaseIoAddressBM_0
.MemIo
= MemIo
;
610 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
614 chan
= &deviceExtension
->chan
[c
];
619 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
620 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x200 + (i
<< 2) + offs12
;
621 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
623 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x238 + offs7
;
624 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
626 UniataInitSyncBaseIO(chan
);
628 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x260 + offs7
;
629 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
630 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x244 + offs7
;
631 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
632 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ (c
<< 2);
633 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
638 KdPrint2((PRINT_PREFIX
"ATI\n"));
640 case ATA_SILICON_IMAGE_ID
: {
642 if(ChipFlags
& SIIBUG
) {
644 if(ChipType
!= SIIMIO
) {
651 if(VendorID
== ATA_SILICON_IMAGE_ID
) {
652 KdPrint2((PRINT_PREFIX
"New SII\n"));
654 KdPrint2((PRINT_PREFIX
"ATI SATA\n"));
656 //if(deviceExtension->HwFlags & SII4CH) {
657 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
659 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
661 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
662 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
663 KdPrint2((PRINT_PREFIX
"MemIo\n"));
666 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
667 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
669 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
670 ULONG unit01
= (c
& 1);
671 ULONG unit10
= (c
& 2);
673 chan
= &deviceExtension
->chan
[c
];
675 if(deviceExtension
->AltRegMap
) {
676 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
677 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ 0x80 + i
+ (unit01
<< 6) + (unit10
<< 8);
678 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
680 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x8a + (unit01
<< 6) + (unit10
<< 8);
681 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
682 UniataInitSyncBaseIO(chan
);
684 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ 0x00 + (unit01
<< 3) + (unit10
<< 8);
685 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
686 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ 0x02 + (unit01
<< 3) + (unit10
<< 8);
687 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
688 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ 0x04 + (unit01
<< 3) + (unit10
<< 8);
689 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
690 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
691 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
692 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].Addr
= BaseMemAddress
+ 0x10 + (unit01
<< 3) + (unit10
<< 8);
693 chan
->RegTranslation
[IDX_BM_DeviceSpecific0
].MemIo
= MemIo
;
694 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].Addr
= BaseMemAddress
+ 0x40 + (unit01
<< 2) + (unit10
<< 8);
695 chan
->RegTranslation
[IDX_BM_DeviceSpecific1
].MemIo
= MemIo
;
698 if(ChipFlags
& UNIATA_SATA
) {
699 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x104 + (unit01
<< 7) + (unit10
<< 8);
700 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
701 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x108 + (unit01
<< 7) + (unit10
<< 8);
702 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
703 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x100 + (unit01
<< 7) + (unit10
<< 8);
704 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
706 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
711 case ATA_SERVERWORKS_ID
: {
713 if(ChipType
!= SWKSMIO
) {
720 KdPrint2((PRINT_PREFIX
"ServerWorks\n"));
722 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
723 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
725 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
726 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
727 KdPrint2((PRINT_PREFIX
"MemIo\n"));
730 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
731 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
733 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
734 ULONG offs
= c
*0x100;
736 chan
= &deviceExtension
->chan
[c
];
737 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
738 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseMemAddress
+ offs
+ i
*4;
739 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
741 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ offs
+ 0x20;
742 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
743 UniataInitSyncBaseIO(chan
);
745 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x30;
746 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
747 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x32;
748 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
749 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x34;
750 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
752 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ offs
+ 0x40;
753 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
754 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ offs
+ 0x44;
755 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
756 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ offs
+ 0x48;
757 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
759 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
764 //if(ChipType != SIS_SOUTH) {}
765 BOOLEAN SIS_182
=FALSE
;
767 if(!(ChipFlags
& SIS_BASE
)) {
768 KdPrint2((PRINT_PREFIX
"Found SIS_SOUTH\n"));
769 //PrintNtConsole("Found SIS_SOUTH\n");
772 // Make some additional checks
773 KdPrint2((PRINT_PREFIX
"ChipType == SIS_BASE\n"));
774 ChangePciConfig1(0x57, (a
& 0x7f));
775 GetPciConfig4(0x00, tmp32
);
776 if(tmp32
== ATA_SIS5518
) {
777 ChipType
= SIS133NEW
;
778 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133NEW
;
779 deviceExtension
->MaxTransferMode
= ATA_UDMA6
;
780 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
781 //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
783 ChangePciConfig1(0x57, (a
| 0x80));
785 static BUSMASTER_CONTROLLER_INFORMATION
const SiSSouthAdapters
[] = {
786 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
787 // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
788 PCI_DEV_HW_SPEC_BM( ffff
, ffff
, 0xff, -1, NULL
, -1 )
791 GetPciConfig1(0x4a, tmp8
);
792 ChangePciConfig1(0x4a, (a
| 0x10));
793 if(tmp32
== ATA_SIS5513
||
794 tmp32
== ATA_SIS5517
) {
795 i
= AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION
*)&SiSSouthAdapters
[0],
796 -1, HwDeviceExtension
, SystemIoBusNumber
, PCISLOTNUM_NOT_SPECIFIED
, NULL
);
797 if(i
!= BMLIST_TERMINATOR
) {
798 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS133OLD
;
799 //deviceExtension->MaxTransferMode = ATA_UDMA6;
800 deviceExtension
->MaxTransferMode
= SiSSouthAdapters
[i
].MaxTransferMode
;
801 if(SiSSouthAdapters
[i
].RaidFlags
& UNIATA_SATA
) {
802 deviceExtension
->HwFlags
|= UNIATA_SATA
;
803 if(SiSSouthAdapters
[i
].nDeviceId
== 0x1182) {
808 // SiS-South not found
809 if(tmp32
== ATA_SIS5517
) {
810 deviceExtension
->HwFlags
= (deviceExtension
->HwFlags
& ~CHIPTYPE_MASK
) | SIS100NEW
;
811 deviceExtension
->MaxTransferMode
= ATA_UDMA5
;
814 KdPrint2((PRINT_PREFIX
"Generic SiS DMA\n"));
819 SetPciConfig1(0x4a, tmp8
);
820 KdPrint2((PRINT_PREFIX
"UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension
->MaxTransferMode
));
821 //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
822 if(deviceExtension
->HwFlags
& UNIATA_SATA
) {
823 KdPrint2((PRINT_PREFIX
"SiS SATA\n"));
825 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
827 KdPrint2((PRINT_PREFIX
"BaseMemAddress %x\n", BaseMemAddress
));
828 if((*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
829 KdPrint2((PRINT_PREFIX
"MemIo\n"));
832 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
833 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
835 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
836 ULONG offs
= c
<< (SIS_182
? 5 : 6);
838 chan
= &deviceExtension
->chan
[c
];
839 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0 + offs
;
840 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
841 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + offs
;
842 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
843 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + offs
;
844 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
846 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
850 //ChangePciConfig1(0x57, (a | 0x80));
855 if(ChipFlags
& VIASATA
) {
856 /* 2 SATA without SATA registers on first channel + 1 PATA on second */
857 // do nothing, generic PATA INIT
858 KdPrint2((PRINT_PREFIX
"VIA SATA without SATA regs\n"));
861 if(ChipFlags
& UNIATA_SATA
) {
864 ULONG BaseMemAddress
= 0;
867 case 0x3149: // VIA 6420
868 KdPrint2((PRINT_PREFIX
"VIA 6420\n"));
871 case 0x3249: // VIA 6421
872 KdPrint2((PRINT_PREFIX
"VIA 6421\n"));
877 KdPrint2((PRINT_PREFIX
"IoSize %x\n", IoSize
));
878 /*deviceExtension->*/BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
879 5, 0, IoSize
* deviceExtension
->NumberChannels
);
880 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
881 KdPrint2((PRINT_PREFIX
"MemIo\n"));
884 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
885 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
887 if(/*deviceExtension->*/BaseMemAddress
) {
888 KdPrint2((PRINT_PREFIX
"UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress
));
889 if(ChipFlags
& VIABAR
) {
891 ULONG BaseIoAddressBM_0
;
894 KdPrint2((PRINT_PREFIX
"UniataChipDetect: VIABAR\n"));
895 /*deviceExtension->*/BaseIoAddressBM_0
= /*(PIDE_BUSMASTER_REGISTERS)*/
896 AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, 4, 0,
897 sizeof(IDE_BUSMASTER_REGISTERS
)*deviceExtension
->NumberChannels
);
898 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
899 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
901 chan
= &deviceExtension
->chan
[c
];
903 BaseIo
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
, c
, 0, /*0x80*/ sizeof(IDE_REGISTERS_1
) + sizeof(IDE_REGISTERS_2
)*2);
905 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
906 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIo
+ i
;
908 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseIo
+ sizeof(IDE_REGISTERS_1
) + 2;
909 UniataInitSyncBaseIO(chan
);
911 for (i
=0; i
<=IDX_BM_IO_SZ
; i
++) {
912 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
+ sizeof(IDE_BUSMASTER_REGISTERS
)*c
+ i
;
917 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
918 chan
= &deviceExtension
->chan
[c
];
919 if((ChipFlags
& VIABAR
) && (c
==2)) {
920 // Do not setup SATA registers for PATA part
921 for (i
=0; i
<=IDX_SATA_IO_SZ
; i
++) {
922 chan
->RegTranslation
[IDX_SATA_IO
+i
].Addr
= 0;
923 chan
->RegTranslation
[IDX_SATA_IO
+i
].MemIo
= 0;
927 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ (c
* IoSize
);
928 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
929 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 4 + (c
* IoSize
);
930 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
931 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 8 + (c
* IoSize
);
932 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
934 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
943 if(!(ChipFlags
& UNIATA_SATA
)) {
947 /* the intel 31244 needs special care if in DPA mode */
948 if(DeviceID
== 3200 && // Intel 31244
949 pciData
->SubClass
!= PCI_DEV_SUBCLASS_IDE
) {
951 KdPrint2((PRINT_PREFIX
"UniataChipDetect: Intel 31244, DPA mode\n"));
952 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
954 if((*ConfigInfo
->AccessRanges
)[0].RangeInMemory
) {
955 KdPrint2((PRINT_PREFIX
"MemIo\n"));
958 deviceExtension
->AltRegMap
= TRUE
; // inform generic resource allocator
959 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
960 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
962 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
963 ULONG offs
= 0x200 + c
*0x200;
965 chan
= &deviceExtension
->chan
[c
];
966 for (i
=0; i
<=IDX_IO1_SZ
; i
++) {
967 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= MemIo
;
968 chan
->RegTranslation
[IDX_IO1_o
+i
].MemIo
= MemIo
;
971 chan
->RegTranslation
[IDX_IO1_i_Data
].Addr
= BaseMemAddress
+ 0x00 + offs
;
972 chan
->RegTranslation
[IDX_IO1_i_Error
].Addr
= BaseMemAddress
+ 0x04 + offs
;
973 chan
->RegTranslation
[IDX_IO1_i_BlockCount
].Addr
= BaseMemAddress
+ 0x08 + offs
;
974 chan
->RegTranslation
[IDX_IO1_i_BlockNumber
].Addr
= BaseMemAddress
+ 0x0c + offs
;
975 chan
->RegTranslation
[IDX_IO1_i_CylinderLow
].Addr
= BaseMemAddress
+ 0x10 + offs
;
976 chan
->RegTranslation
[IDX_IO1_i_CylinderHigh
].Addr
= BaseMemAddress
+ 0x14 + offs
;
977 chan
->RegTranslation
[IDX_IO1_i_DriveSelect
].Addr
= BaseMemAddress
+ 0x18 + offs
;
978 chan
->RegTranslation
[IDX_IO1_i_Status
].Addr
= BaseMemAddress
+ 0x1c + offs
;
980 UniataInitSyncBaseIO(chan
);
982 chan
->RegTranslation
[IDX_IO1_o_Command
].Addr
= BaseMemAddress
+ 0x1d + offs
;
983 chan
->RegTranslation
[IDX_IO1_o_Feature
].Addr
= BaseMemAddress
+ 0x06 + offs
;
984 chan
->RegTranslation
[IDX_IO2_o_Control
].Addr
= BaseMemAddress
+ 0x29 + offs
;
986 chan
->RegTranslation
[IDX_IO2_AltStatus
].Addr
= BaseMemAddress
+ 0x28 + offs
;
987 chan
->RegTranslation
[IDX_IO2_AltStatus
].MemIo
= MemIo
;
989 chan
->RegTranslation
[IDX_BM_Command
].Addr
= BaseMemAddress
+ offs
+ 0x70;
990 chan
->RegTranslation
[IDX_BM_Command
].MemIo
= MemIo
;
991 chan
->RegTranslation
[IDX_BM_Status
].Addr
= BaseMemAddress
+ offs
+ 0x72;
992 chan
->RegTranslation
[IDX_BM_Status
].MemIo
= MemIo
;
993 chan
->RegTranslation
[IDX_BM_PRD_Table
].Addr
= BaseMemAddress
+ offs
+ 0x74;
994 chan
->RegTranslation
[IDX_BM_PRD_Table
].MemIo
= MemIo
;
996 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= BaseMemAddress
+ 0x100 + offs
;
997 chan
->RegTranslation
[IDX_SATA_SStatus
].MemIo
= MemIo
;
998 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= BaseMemAddress
+ 0x104 + offs
;
999 chan
->RegTranslation
[IDX_SATA_SError
].MemIo
= MemIo
;
1000 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= BaseMemAddress
+ 0x108 + offs
;
1001 chan
->RegTranslation
[IDX_SATA_SControl
].MemIo
= MemIo
;
1003 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1008 if(deviceExtension
->MaxTransferMode
>= ATA_SA150
) {
1009 GetPciConfig1(0x90, tmp8
);
1010 KdPrint2((PRINT_PREFIX
"Intel chip config: %x\n", tmp8
));
1011 /* SATA parts can be either compat or AHCI */
1012 if(ChipFlags
& UNIATA_AHCI
) {
1015 //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
1017 KdPrint2((PRINT_PREFIX
"try run AHCI\n"));
1020 KdPrint2((PRINT_PREFIX
"Compatible mode\n"));
1022 deviceExtension
->HwFlags
&= ~UNIATA_AHCI
;
1024 /* if BAR(5) is IO it should point to SATA interface registers */
1025 if(deviceExtension
->DevID
== 0x28288086 &&
1026 pciData
->u
.type0
.SubVendorID
== 0x106b) {
1027 /* Skip BAR(5) on ICH8M Apples, system locks up on access. */
1028 KdPrint2((PRINT_PREFIX
"Ignore BAR5 on ICH8M Apples\n"));
1031 BaseMemAddress
= AtapiGetIoRange(HwDeviceExtension
, ConfigInfo
, pciData
, SystemIoBusNumber
,
1033 if(BaseMemAddress
&& (*ConfigInfo
->AccessRanges
)[5].RangeInMemory
) {
1034 KdPrint2((PRINT_PREFIX
"MemIo\n"));
1038 deviceExtension
->BaseIoAddressSATA_0
.Addr
= BaseMemAddress
;
1039 deviceExtension
->BaseIoAddressSATA_0
.MemIo
= MemIo
;
1041 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1042 chan
= &deviceExtension
->chan
[c
];
1044 if(ChipFlags
& ICH5
) {
1045 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1046 if ((tmp8
& 0x04) == 0) {
1047 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1048 } else if ((tmp8
& 0x02) == 0) {
1051 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1053 } else if ((tmp8
& 0x02) != 0) {
1056 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1060 if(ChipFlags
& I6CH2
) {
1061 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1062 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1064 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1065 switch(tmp8
& 0x03) {
1082 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1083 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1086 if(/*(ChipFlags & ICH5) &&*/ BaseMemAddress
) {
1087 KdPrint2((PRINT_PREFIX
"BaseMemAddress[5] -> indexed\n"));
1088 chan
->RegTranslation
[IDX_INDEXED_ADDR
].Addr
= BaseMemAddress
+ 0;
1089 chan
->RegTranslation
[IDX_INDEXED_ADDR
].MemIo
= MemIo
;
1090 chan
->RegTranslation
[IDX_INDEXED_DATA
].Addr
= BaseMemAddress
+ 4;
1091 chan
->RegTranslation
[IDX_INDEXED_DATA
].MemIo
= MemIo
;
1093 if((ChipFlags
& ICH5
) || BaseMemAddress
) {
1095 KdPrint2((PRINT_PREFIX
"io indexed\n"));
1096 // Rather interesting way of register access...
1097 ChipType
= INTEL_IDX
;
1098 deviceExtension
->HwFlags
&= ~CHIPTYPE_MASK
;
1099 deviceExtension
->HwFlags
|= ChipType
;
1101 chan
->RegTranslation
[IDX_SATA_SStatus
].Addr
= 0x200*c
+ 0;
1102 chan
->RegTranslation
[IDX_SATA_SStatus
].Proc
= 1;
1103 chan
->RegTranslation
[IDX_SATA_SError
].Addr
= 0x200*c
+ 2;
1104 chan
->RegTranslation
[IDX_SATA_SError
].Proc
= 1;
1105 chan
->RegTranslation
[IDX_SATA_SControl
].Addr
= 0x200*c
+ 1;
1106 chan
->RegTranslation
[IDX_SATA_SControl
].Proc
= 1;
1112 // rest of INIT staff is in AtapiChipInit()
1117 /* Cyrix 5530 ATA33 controller */
1118 if(deviceExtension
->DevID
== 0x01021078) {
1119 ConfigInfo
->AlignmentMask
= 0x0f;
1120 deviceExtension
->MaximumDmaTransferLength
= 63*1024;
1123 case ATA_JMICRON_ID
:
1124 /* New JMicron PATA controllers */
1125 GetPciConfig1(0xdf, tmp8
);
1127 KdPrint((" Check JMicron AHCI\n"));
1128 if(Ata_is_ahci_dev(pciData
)) {
1129 ChipFlags
|= UNIATA_AHCI
;
1130 deviceExtension
->HwFlags
|= UNIATA_AHCI
;
1132 KdPrint((" JMicron PATA\n"));
1135 /* set controller configuration to a combined setup we support */
1136 SetPciConfig4(0x40, 0x80c0a131);
1137 SetPciConfig4(0x80, 0x01200000);
1138 //KdPrint((" JMicron Combined (not supported yet)\n"));
1139 //return STATUS_NOT_FOUND;
1144 return STATUS_SUCCESS
;
1146 } // end UniataChipDetect()
1150 Do some 'magic staff' for VIA SouthBridge
1151 This will prevent data losses
1155 AtapiViaSouthBridgeFixup(
1156 IN PVOID HwDeviceExtension
,
1157 IN BUS_DATA_TYPE BusDataType
,
1158 IN ULONG SystemIoBusNumber
,
1162 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1163 PCI_COMMON_CONFIG pciData
;
1169 PCI_SLOT_NUMBER slotData
;
1171 BOOLEAN found
= FALSE
;
1173 slotData
.u
.AsULONG
= slotNumber
;
1174 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1176 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1178 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1183 PCI_COMMON_HDR_LENGTH
);
1185 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1189 VendorID
= pciData
.VendorID
;
1190 DeviceID
= pciData
.DeviceID
;
1191 dev_id
= (VendorID
| (DeviceID
<< 16));
1193 if (dev_id
== 0x03051106 || /* VIA VT8363 */
1194 dev_id
== 0x03911106 || /* VIA VT8371 */
1195 dev_id
== 0x31021106 || /* VIA VT8662 */
1196 dev_id
== 0x31121106) { /* VIA VT8361 */
1199 GetPciConfig1(0x76, reg76
);
1201 if ((reg76
& 0xf0) != 0xd0) {
1202 SetPciConfig1(0x75, 0x80);
1203 SetPciConfig1(0x76, (reg76
& 0x0f) | 0xd0);
1210 deviceExtension
->HwFlags
&= ~VIABUG
;
1212 } // end AtapiViaSouthBridgeFixup()
1215 Do some 'magic staff' for ROSB SouthBridge
1216 This will prevent data losses
1220 AtapiRosbSouthBridgeFixup(
1221 IN PVOID HwDeviceExtension
,
1222 IN BUS_DATA_TYPE BusDataType
,
1223 IN ULONG SystemIoBusNumber
,
1227 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1228 PCI_COMMON_CONFIG pciData
;
1234 PCI_SLOT_NUMBER slotData
;
1236 // BOOLEAN found = FALSE;
1238 /* locate the ISA part in the southbridge and enable UDMA33 */
1239 slotData
.u
.AsULONG
= slotNumber
;
1240 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1242 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1244 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1249 PCI_COMMON_HDR_LENGTH
);
1251 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1255 VendorID
= pciData
.VendorID
;
1256 DeviceID
= pciData
.DeviceID
;
1257 dev_id
= (VendorID
| (DeviceID
<< 16));
1259 if (dev_id
== ATA_ROSB4_ISA
) { /* */
1260 ChangePciConfig4(0x64, ((a
& ~0x00002000) | 0x00004000));
1264 } // end AtapiRosbSouthBridgeFixup()
1267 Do some 'magic staff' for ROSB SouthBridge
1268 This will prevent data losses
1272 AtapiAliSouthBridgeFixup(
1273 IN PVOID HwDeviceExtension
,
1274 IN BUS_DATA_TYPE BusDataType
,
1275 IN ULONG SystemIoBusNumber
,
1276 IN ULONG slotNumber
,
1280 //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1281 PCI_COMMON_CONFIG pciData
;
1287 PCI_SLOT_NUMBER slotData
;
1289 // BOOLEAN found = FALSE;
1291 /* workaround for datacorruption bug found on at least SUN Blade-100
1292 * find the ISA function on the southbridge and disable then enable
1293 * the ATA channel tristate buffer */
1294 slotData
.u
.AsULONG
= slotNumber
;
1295 for(funcNumber
= 0; funcNumber
< PCI_MAX_FUNCTION
; funcNumber
++) {
1297 slotData
.u
.bits
.FunctionNumber
= funcNumber
;
1299 busDataRead
= ScsiPortGetBusData(HwDeviceExtension
,
1304 PCI_COMMON_HDR_LENGTH
);
1306 if (busDataRead
< (ULONG
)PCI_COMMON_HDR_LENGTH
) {
1310 VendorID
= pciData
.VendorID
;
1311 DeviceID
= pciData
.DeviceID
;
1312 dev_id
= (VendorID
| (DeviceID
<< 16));
1314 if (dev_id
== ATA_ALI_1533
) { /* SOUTH */
1315 ChangePciConfig1(0x58, (a
& ~(0x04 << c
)));
1316 ChangePciConfig1(0x58, (a
| (0x04 << c
)));
1320 } // end AtapiRosbSouthBridgeFixup()
1325 IN PHW_DEVICE_EXTENSION deviceExtension
,
1326 IN ULONG channel
// physical channel number (0-1)
1329 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1330 ULONG slotNumber
= deviceExtension
->slotNumber
;
1331 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1333 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1335 UCHAR reg
, val
, res
;
1336 PCI_SLOT_NUMBER slotData
;
1338 slotData
.u
.AsULONG
= deviceExtension
->slotNumber
;
1340 if(ChipType
== HPT374
&& slotData
.u
.bits
.FunctionNumber
== 1) {
1341 reg
= channel
? 0x57 : 0x53;
1342 GetPciConfig1(reg
, val
);
1343 SetPciConfig1(reg
, val
| 0x80);
1347 GetPciConfig1(reg
, val
);
1348 SetPciConfig1(reg
, val
& 0xfe);
1350 GetPciConfig1(0x5a, res
);
1351 res
= res
& (channel
? 0x01 : 0x02);
1352 SetPciConfig1(reg
, val
);
1353 KdPrint2((PRINT_PREFIX
"hpt_cable80(%d) = %d\n", channel
, !res
));
1355 } // end hpt_cable80()
1361 IN PHW_DEVICE_EXTENSION deviceExtension,
1362 IN ULONG channel // physical channel number (0-1)
1365 PVOID HwDeviceExtension = (PVOID)deviceExtension;
1366 ULONG slotNumber = deviceExtension->slotNumber;
1367 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
1369 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1376 GetPciConfig1(0x50, reg50);
1393 for (j=0; j>=2; i -= 8) {
1394 i = (3-(channel*2+j))*8;
1395 if (((reg50 >> (i & 0x10)) & 8) &&
1396 ((reg50 >> i) & 0x20) &&
1397 (((reg50 >> i) & 7) < a)) {
1399 res |= TRUE; //(1 << (1 - (i >> 4)));
1402 KdPrint2((PRINT_PREFIX "via_cable80(%d) = %d\n", channel, res));
1405 } // end via_cable80()
1411 IN PHW_DEVICE_EXTENSION deviceExtension
,
1412 IN ULONG channel
, // physical channel number (0-1)
1417 PVOID HwDeviceExtension
= (PVOID
)deviceExtension
;
1418 ULONG slotNumber
= deviceExtension
->slotNumber
;
1419 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1421 //ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
1423 ULONG c
; // logical channel (for Compatible Mode controllers)
1426 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1427 chan
= &deviceExtension
->chan
[c
];
1429 GetPciConfig1(pci_reg
, tmp8
);
1430 if(!(tmp8
& (1 << (channel
<< bit_offs
)))) {
1431 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1432 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 0\n", channel
, pci_reg
, bit_offs
));
1436 KdPrint2((PRINT_PREFIX
"generic_cable80(%d, %#x, %d) = 1\n", channel
, pci_reg
, bit_offs
));
1438 } // end generic_cable80()
1442 UniAtaReadLunConfig(
1443 IN PHW_DEVICE_EXTENSION deviceExtension
,
1444 IN ULONG channel
, // physical channel
1445 IN ULONG DeviceNumber
1450 PHW_LU_EXTENSION LunExt
;
1453 c
= channel
- deviceExtension
->Channel
; // logical channel
1455 chan
= &deviceExtension
->chan
[c
];
1456 DeviceNumber
= (DeviceNumber
% deviceExtension
->NumberLuns
);
1457 LunExt
= chan
->lun
[DeviceNumber
];
1459 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadCacheEnable", 1);
1460 LunExt
->opt_ReadCacheEnable
= tmp32
? TRUE
: FALSE
;
1462 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"WriteCacheEnable", 1);
1463 LunExt
->opt_WriteCacheEnable
= tmp32
? TRUE
: FALSE
;
1465 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1466 LunExt
->opt_MaxTransferMode
= tmp32
;
1468 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"PreferedTransferMode", 0xffffffff);
1469 LunExt
->opt_PreferedTransferMode
= tmp32
;
1471 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"ReadOnly", 0);
1473 LunExt
->opt_ReadOnly
= (UCHAR
)tmp32
;
1476 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"GeomType", 0xffffffff);
1477 if(tmp32
> GEOM_MANUAL
) {
1480 LunExt
->opt_GeomType
= tmp32
;
1481 if(tmp32
== GEOM_MANUAL
) {
1482 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1483 LunExt
->opt_GeomType
= GEOM_ORIG
;
1484 // assume IdentifyData is already zero-filled
1485 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"C", 0);
1486 LunExt
->IdentifyData
.NumberOfCurrentCylinders
=
1487 LunExt
->IdentifyData
.NumberOfCylinders
= (USHORT
)tmp32
;
1488 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"H", 0);
1489 LunExt
->IdentifyData
.NumberOfCurrentHeads
=
1490 LunExt
->IdentifyData
.NumberOfHeads
= (USHORT
)tmp32
;
1491 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"S", 0);
1492 LunExt
->IdentifyData
.CurrentSectorsPerTrack
=
1493 LunExt
->IdentifyData
.SectorsPerTrack
= (USHORT
)tmp32
;
1494 memcpy(LunExt
->IdentifyData
.ModelNumber
, "SEIDH DD", 8); // ESDI HDD
1495 memcpy(LunExt
->IdentifyData
.SerialNumber
, ".10", 4);
1496 memcpy(LunExt
->IdentifyData
.FirmwareRevision
, ".10", 4);
1497 if(!LunExt
->IdentifyData
.SectorsPerTrack
||
1498 !LunExt
->IdentifyData
.NumberOfCylinders
||
1499 !LunExt
->IdentifyData
.SectorsPerTrack
) {
1501 KdPrint2((PRINT_PREFIX
"Wrong CHS\n"));
1502 LunExt
->opt_GeomType
= GEOM_AUTO
;
1504 LunExt
->DeviceFlags
|= DFLAGS_MANUAL_CHS
;
1505 LunExt
->opt_GeomType
= GEOM_ORIG
;
1509 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DeviceNumber
, L
"Hidden", 0);
1511 LunExt
->DeviceFlags
|= DFLAGS_HIDDEN
;
1516 } // end UniAtaReadLunConfig()
1520 AtapiReadChipConfig(
1521 IN PVOID HwDeviceExtension
,
1522 IN ULONG DeviceNumber
,
1523 IN ULONG channel
// physical channel
1526 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1529 ULONG c
; // logical channel (for Compatible Mode controllers)
1532 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: devExt %#x\n", deviceExtension
));
1533 ASSERT(deviceExtension
);
1535 if(channel
!= CHAN_NOT_SPECIFIED
) {
1536 c
= channel
- deviceExtension
->Channel
; // logical channel (for Compatible Mode controllers)
1538 c
= CHAN_NOT_SPECIFIED
;
1541 KdPrint2((PRINT_PREFIX
"AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber
, channel
));
1543 if(channel
== CHAN_NOT_SPECIFIED
) {
1544 if(AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"ForceSimplex", FALSE
)) {
1545 deviceExtension
->simplexOnly
= TRUE
;
1547 deviceExtension
->opt_AtapiDmaZeroTransfer
= FALSE
;
1548 deviceExtension
->opt_AtapiDmaControlCmd
= FALSE
;
1549 deviceExtension
->opt_AtapiDmaRawRead
= g_opt_AtapiDmaRawRead
;
1550 deviceExtension
->opt_AtapiDmaReadWrite
= TRUE
;
1553 if(c
== CHAN_NOT_SPECIFIED
) {
1554 KdPrint2((PRINT_PREFIX
"MaxTransferMode (base): %#x\n", deviceExtension
->MaxTransferMode
));
1555 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1556 chan
= &deviceExtension
->chan
[c
];
1557 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1558 tmp32
= AtapiRegCheckDevValue(deviceExtension
, channel
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1559 if(tmp32
!= 0xffffffff) {
1560 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1561 chan
->MaxTransferMode
= tmp32
;
1563 //UniAtaReadLunConfig(deviceExtension, c, 0);
1564 //UniAtaReadLunConfig(deviceExtension, c, 1);
1567 deviceExtension
->opt_AtapiDmaZeroTransfer
=
1568 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaZeroTransfer", deviceExtension
->opt_AtapiDmaZeroTransfer
) ?
1571 deviceExtension
->opt_AtapiDmaControlCmd
=
1572 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaControlCmd", deviceExtension
->opt_AtapiDmaControlCmd
) ?
1575 deviceExtension
->opt_AtapiDmaRawRead
=
1576 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaRawRead", deviceExtension
->opt_AtapiDmaRawRead
) ?
1579 deviceExtension
->opt_AtapiDmaReadWrite
=
1580 AtapiRegCheckDevValue(deviceExtension
, CHAN_NOT_SPECIFIED
, DEVNUM_NOT_SPECIFIED
, L
"AtapiDmaReadWrite", deviceExtension
->opt_AtapiDmaReadWrite
) ?
1584 chan
= &deviceExtension
->chan
[c
];
1585 chan
->MaxTransferMode
= deviceExtension
->MaxTransferMode
;
1586 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"MaxTransferMode", chan
->MaxTransferMode
);
1587 if(tmp32
!= 0xffffffff) {
1588 KdPrint2((PRINT_PREFIX
"MaxTransferMode (overriden): %#x\n", chan
->MaxTransferMode
));
1589 chan
->MaxTransferMode
= tmp32
;
1591 tmp32
= AtapiRegCheckDevValue(deviceExtension
, c
, DEVNUM_NOT_SPECIFIED
, L
"ReorderEnable", TRUE
);
1592 chan
->UseReorder
= tmp32
? TRUE
: FALSE
;
1594 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
1595 UniAtaReadLunConfig(deviceExtension
, channel
, i
);
1600 } // end AtapiReadChipConfig()
1605 IN PVOID HwDeviceExtension
,
1606 IN ULONG DeviceNumber
,
1607 IN ULONG channel
// logical channel
1610 PHW_DEVICE_EXTENSION deviceExtension
= (PHW_DEVICE_EXTENSION
)HwDeviceExtension
;
1611 ULONG slotNumber
= deviceExtension
->slotNumber
;
1612 ULONG SystemIoBusNumber
= deviceExtension
->SystemIoBusNumber
;
1613 ULONG VendorID
= deviceExtension
->DevID
& 0xffff;
1614 ULONG DeviceID
= (deviceExtension
->DevID
>> 16) & 0xffff;
1615 ULONG RevID
= deviceExtension
->RevID
;
1617 // BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
1618 ULONG ChipType
= deviceExtension
->HwFlags
& CHIPTYPE_MASK
;
1619 ULONG ChipFlags
= deviceExtension
->HwFlags
& CHIPFLAG_MASK
;
1624 ULONG c
; // logical channel (for Compatible Mode controllers)
1625 BOOLEAN CheckCable
= FALSE
;
1626 //ULONG BaseIoAddress;
1629 case CHAN_NOT_SPECIFIED_CHECK_CABLE
:
1632 case CHAN_NOT_SPECIFIED
:
1633 c
= CHAN_NOT_SPECIFIED
;
1636 //c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
1638 channel
+= deviceExtension
->Channel
;
1641 KdPrint2((PRINT_PREFIX
"AtapiChipInit: dev %#x, ph chan %d, c %d\n", DeviceNumber
, channel
, c
));
1643 KdPrint2((PRINT_PREFIX
"HwFlags: %#x\n", deviceExtension
->HwFlags
));
1644 KdPrint2((PRINT_PREFIX
"VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID
, DeviceID
, RevID
));
1646 if(deviceExtension
->UnknownDev
) {
1647 KdPrint2((PRINT_PREFIX
" Unknown chip\n" ));
1649 VendorID
= 0xffffffff;
1653 if(ChipFlags
& UNIATA_AHCI
) {
1654 /* if BAR(5) is IO it should point to SATA interface registers */
1655 if(!deviceExtension
->BaseIoAHCI_0
.Addr
) {
1656 KdPrint2((PRINT_PREFIX
" !BaseIoAHCI_0, exiting\n" ));
1659 if(c
== CHAN_NOT_SPECIFIED
) {
1660 return UniataAhciInit(HwDeviceExtension
);
1662 if(c
<deviceExtension
->NumberChannels
) {
1663 KdPrint2((PRINT_PREFIX
" AHCI single channel init\n" ));
1664 UniataAhciReset(HwDeviceExtension
, c
);
1667 KdPrint2((PRINT_PREFIX
" AHCI non-existent channel\n" ));
1673 // case ATA_ACARD_ID:
1675 case ATA_ACER_LABS_ID
:
1676 if(ChipFlags
& UNIATA_SATA
) {
1677 if(c
== CHAN_NOT_SPECIFIED
) {
1678 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
1679 chan
= &deviceExtension
->chan
[c
];
1680 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1681 /* the southbridge might need the data corruption fix */
1682 if(RevID
== 0xc2 || RevID
== 0xc3) {
1683 AtapiAliSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1684 SystemIoBusNumber
, slotNumber
, c
);
1687 /* enable PCI interrupt */
1688 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1691 if(ChipFlags
& ALINEW
) {
1692 if(c
== CHAN_NOT_SPECIFIED
) {
1693 /* use device interrupt as byte count end */
1694 ChangePciConfig1(0x4a, (a
| 0x20));
1695 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
1697 ChangePciConfig1(0x4b, (a
| 0x09));
1700 /* enable ATAPI UDMA mode */
1701 ChangePciConfig1(0x53, (a
| (RevID
>= 0xc7 ? 0x03 : 0x01)));
1704 // check 80-pin cable
1705 generic_cable80(deviceExtension
, channel
, 0x4a, 0);
1708 if(c
== CHAN_NOT_SPECIFIED
) {
1709 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
1710 ChangePciConfig1(0x53, (a
| 0x03));
1713 deviceExtension
->chan
[c
].ChannelCtrlFlags
|= CTRFLAGS_DMA_RO
;
1718 if(c
== CHAN_NOT_SPECIFIED
) {
1719 /* set prefetch, postwrite */
1720 if(ChipFlags
& AMDBUG
) {
1721 ChangePciConfig1(0x41, (a
& 0x0f));
1723 ChangePciConfig1(0x41, (a
| 0xf0));
1726 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1728 // check 80-pin cable
1729 if(!(ChipFlags
& UNIATA_NO80CHK
)) {
1730 if(c
== CHAN_NOT_SPECIFIED
) {
1733 generic_cable80(deviceExtension
, channel
, 0x42, 0);
1737 case ATA_HIGHPOINT_ID
:
1739 if(c
== CHAN_NOT_SPECIFIED
) {
1741 if(ChipFlags
& HPTOLD
) {
1742 /* turn off interrupt prediction */
1743 ChangePciConfig1(0x51, (a
& ~0x80));
1745 /* turn off interrupt prediction */
1746 ChangePciConfig1(0x51, (a
& ~0x03));
1747 ChangePciConfig1(0x55, (a
& ~0x03));
1748 /* turn on interrupts */
1749 ChangePciConfig1(0x5a, (a
& ~0x10));
1750 /* set clocks etc */
1751 if(ChipType
< HPT372
) {
1752 SetPciConfig1(0x5b, 0x22);
1754 ChangePciConfig1(0x5b, ((a
& 0x01) | 0x20));
1759 // check 80-pin cable
1760 chan
= &deviceExtension
->chan
[c
];
1761 if(!hpt_cable80(deviceExtension
, channel
)) {
1762 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1766 case ATA_INTEL_ID
: {
1770 if(ChipFlags
& UNIATA_SATA
) {
1772 KdPrint2((PRINT_PREFIX
"Intel SATA\n"));
1773 if(ChipFlags
& UNIATA_AHCI
) {
1774 KdPrint2((PRINT_PREFIX
"Do nothing for AHCI\n"));
1777 if(c
== CHAN_NOT_SPECIFIED
) {
1778 KdPrint2((PRINT_PREFIX
"Base init\n"));
1779 /* force all ports active "the legacy way" */
1780 ChangePciConfig2(0x92, (a
| 0x0f));
1781 /* enable PCI interrupt */
1782 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
1786 KdPrint2((PRINT_PREFIX
"channel init\n"));
1788 GetPciConfig1(0x90, tmp8
);
1789 KdPrint2((PRINT_PREFIX
"reg 90: %x, init lun map\n", tmp8
));
1791 KdPrint2((PRINT_PREFIX
"chan %d\n", c
));
1792 chan
= &deviceExtension
->chan
[c
];
1794 if(ChipFlags
& ICH5
) {
1795 KdPrint2((PRINT_PREFIX
"ICH5\n"));
1796 if ((tmp8
& 0x04) == 0) {
1797 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1798 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ^ c
;
1799 chan
->lun
[1]->SATA_lun_map
= 0;
1800 } else if ((tmp8
& 0x02) == 0) {
1802 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
1803 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
1806 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1808 } else if ((tmp8
& 0x02) != 0) {
1810 chan
->lun
[0]->SATA_lun_map
= (tmp8
& 0x01) ? 1 : 0;
1811 chan
->lun
[1]->SATA_lun_map
= (tmp8
& 0x01) ? 0 : 1;
1814 //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
1818 if(ChipFlags
& I6CH2
) {
1819 KdPrint2((PRINT_PREFIX
"I6CH2\n"));
1820 chan
->ChannelCtrlFlags
|= CTRFLAGS_NO_SLAVE
;
1821 chan
->lun
[0]->SATA_lun_map
= c
? 0 : 1;
1822 chan
->lun
[1]->SATA_lun_map
= 0;
1824 KdPrint2((PRINT_PREFIX
"other Intel\n"));
1825 switch(tmp8
& 0x03) {
1827 chan
->lun
[0]->SATA_lun_map
= 0+c
;
1828 chan
->lun
[1]->SATA_lun_map
= 2+c
;
1832 chan
->lun
[0]->SATA_lun_map
= 0;
1833 chan
->lun
[1]->SATA_lun_map
= 2;
1841 chan
->lun
[0]->SATA_lun_map
= 1;
1842 chan
->lun
[1]->SATA_lun_map
= 3;
1852 KdPrint2((PRINT_PREFIX
"PATA part\n"));
1853 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
1856 if(ChipType
== INTEL_IDX
) {
1857 KdPrint2((PRINT_PREFIX
"io indexed\n"));
1858 //for(c=0; c<deviceExtension->NumberChannels; c++) {
1859 chan
= &deviceExtension
->chan
[c
];
1860 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
1861 if(!(chan
->ChannelCtrlFlags
& CTRFLAGS_NO_SLAVE
)) {
1862 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 1);
1870 if(deviceExtension
->MaxTransferMode
< ATA_UDMA2
)
1872 // check 80-pin cable
1873 if(c
== CHAN_NOT_SPECIFIED
) {
1876 chan
= &deviceExtension
->chan
[c
];
1877 GetPciConfig2(0x54, reg54
);
1878 if( ((reg54
>> (channel
*2)) & 30) != 30) {
1879 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1883 case ATA_NVIDIA_ID
: {
1884 if(ChipFlags
& UNIATA_SATA
) {
1885 if(c
== CHAN_NOT_SPECIFIED
) {
1886 ULONG offs
= (ChipFlags
& NV4OFF
) ? 0x0440 : 0x0010;
1887 /* enable control access */
1888 ChangePciConfig1(0x50, (a
| 0x04));
1889 /* MCP55 seems to need some time to allow r_res2 read. */
1890 AtapiStallExecution(10);
1891 KdPrint2((PRINT_PREFIX
"BaseIoAddressSATA_0=%x\n", deviceExtension
->BaseIoAddressSATA_0
.Addr
));
1892 if(ChipFlags
& NVQ
) {
1893 /* clear interrupt status */
1894 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0x00ff00ff);
1895 /* enable device and PHY state change interrupts */
1896 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+4, 0x000d000d);
1897 /* disable NCQ support */
1898 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400,
1899 AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0400) & 0xfffffff9);
1901 /* clear interrupt status */
1902 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
, 0xff);
1903 /* enable device and PHY state change interrupts */
1904 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),offs
+1, 0xdd);
1906 /* enable PCI interrupt */
1907 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG
, Command
), (a
& ~0x0400));
1909 //UniataSataPhyEnable(HwDeviceExtension, c);
1914 if(c
== CHAN_NOT_SPECIFIED
) {
1915 /* set prefetch, postwrite */
1916 ChangePciConfig1(0x51, (a
& 0x0f));
1918 // check 80-pin cable
1919 generic_cable80(deviceExtension
, channel
, 0x52, 1);
1920 /* chan = &deviceExtension->chan[c];
1921 GetPciConfig1(0x52, reg52);
1922 if( !((reg52 >> (channel*2)) & 0x01)) {
1923 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
1928 case ATA_PROMISE_ID
: {
1933 if(c
== CHAN_NOT_SPECIFIED
) {
1934 // ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
1935 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11,
1936 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x11) | 0x0a );
1940 /* enable burst mode */
1941 // ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
1942 if(c
== CHAN_NOT_SPECIFIED
) {
1943 AtapiWritePortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f,
1944 AtapiReadPortEx1(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x1f) | 0x01 );
1946 // check 80-pin cable
1947 chan
= &deviceExtension
->chan
[c
];
1948 GetPciConfig2(0x50, Reg50
);
1949 if(Reg50
& (1 << (channel
+10))) {
1950 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1955 if(c
== CHAN_NOT_SPECIFIED
) {
1958 // check 80-pin cable
1959 chan
= &deviceExtension
->chan
[c
];
1960 AtapiWritePort1(chan
, IDX_BM_DeviceSpecific0
, 0x0b);
1961 if(AtapiReadPort1(chan
, IDX_BM_DeviceSpecific1
) & 0x04) {
1962 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1967 if(c
== CHAN_NOT_SPECIFIED
) {
1968 if(ChipFlags
& PRSATA
) {
1969 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressBM_0
),0x6c, 0x000000ff);
1972 chan
= &deviceExtension
->chan
[c
];
1973 AtapiWritePort4(chan
, IDX_BM_Command
,
1974 (AtapiReadPort4(chan
, IDX_BM_Command
) & ~0x00000f8f) | channel
);
1975 AtapiWritePort4(chan
, IDX_BM_DeviceSpecific0
, 0x00000001);
1976 // check 80-pin cable
1977 if(chan
->MaxTransferMode
< ATA_SA150
&&
1978 (AtapiReadPort4(chan
, IDX_BM_Command
) & 0x01000000)) {
1979 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
1985 case ATA_SERVERWORKS_ID
:
1986 if(c
== CHAN_NOT_SPECIFIED
) {
1987 if(ChipType
== SWKS33
) {
1988 AtapiRosbSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
1989 SystemIoBusNumber
, slotNumber
);
1991 ChangePciConfig1(0x5a, ((a
& ~0x40) | ((ChipType
== SWKS100
) ? 0x03 : 0x02)));
1996 if(ChipType
== SIIMIO
) {
1997 KdPrint2((PRINT_PREFIX
"ATI New\n"));
2000 KdPrint2((PRINT_PREFIX
"ATI\n"));
2003 case ATA_SILICON_IMAGE_ID
:
2004 /* if(ChipFlags & SIIENINTR) {
2005 SetPciConfig1(0x71, 0x01);
2010 KdPrint2((PRINT_PREFIX
"SII\n"));
2013 if(c
== CHAN_NOT_SPECIFIED
) {
2014 if(ChipFlags
& SIISETCLK
) {
2015 KdPrint2((PRINT_PREFIX
"SIISETCLK\n"));
2016 GetPciConfig1(0x8a, tmp8
);
2017 if ((tmp8
& 0x30) != 0x10)
2018 ChangePciConfig1(0x8a, (a
& 0xcf) | 0x10);
2019 GetPciConfig1(0x8a, tmp8
);
2020 if ((tmp8
& 0x30) != 0x10) {
2021 KdPrint2((PRINT_PREFIX
"Sil 0680 could not set ATA133 clock\n"));
2022 deviceExtension
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA5
);
2026 if(deviceExtension
->MaxTransferMode
< ATA_SA150
) {
2027 // check 80-pin cable
2028 if(c
== CHAN_NOT_SPECIFIED
) {
2031 KdPrint2((PRINT_PREFIX
"Check UDMA66 cable\n"));
2032 chan
= &deviceExtension
->chan
[c
];
2033 GetPciConfig2(0x79, Reg79
);
2034 if(Reg79
& (channel
? 0x02 : 0x01)) {
2035 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2039 ULONG unit01
= (c
& 1);
2040 ULONG unit10
= (c
& 2);
2041 /* enable/disable PHY state change interrupt */
2042 if(c
== CHAN_NOT_SPECIFIED
) {
2043 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2046 if(ChipFlags
& SIINOSATAIRQ
) {
2047 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2048 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2052 if(ChipFlags
& SIINOSATAIRQ
) {
2053 KdPrint2((PRINT_PREFIX
"Disable broken SATA intr on c=%x\n", c
));
2054 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),0);
2056 KdPrint2((PRINT_PREFIX
"Enable SATA intr on c=%x\n", c
));
2057 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
), 0x148 + (unit01
<< 7) + (unit10
<< 8),(1 << 16));
2061 if(c
== CHAN_NOT_SPECIFIED
) {
2062 /* enable interrupt as BIOS might not */
2063 ChangePciConfig1(0x8a, (a
& 0x3f));
2064 // Enable 3rd and 4th channels
2065 if (ChipFlags
& SII4CH
) {
2066 KdPrint2((PRINT_PREFIX
"SII4CH\n"));
2067 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x0200, 0x00000002);
2070 chan
= &deviceExtension
->chan
[c
];
2071 /* dont block interrupts */
2072 //ChangePciConfig4(0x48, (a & ~0x03c00000));
2073 tmp32
= AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2074 AtapiWritePortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48, (1 << 22) << c
);
2076 tmp32
= AtapiReadPortEx4(NULL
, (ULONGIO_PTR
)(&deviceExtension
->BaseIoAddressSATA_0
),0x48);
2078 /* Initialize FIFO PCI bus arbitration */
2079 GetPciConfig1(offsetof(PCI_COMMON_CONFIG
, CacheLineSize
), tmp8
);
2081 KdPrint2((PRINT_PREFIX
"SII: CacheLine=%d\n", tmp32
));
2083 AtapiWritePort2(chan
, IDX_BM_DeviceSpecific1
, ((USHORT
)tmp8
) << 8 | tmp8
);
2085 KdPrint2((PRINT_PREFIX
"SII: CacheLine=0 !!!\n"));
2092 KdPrint2((PRINT_PREFIX
"SII_CMD\n"));
2093 if(c
== CHAN_NOT_SPECIFIED
) {
2094 /* Setup interrupts. */
2095 SetPciConfig1(0x71, 0x01);
2097 /* GetPciConfig1(0x8a, tmp8);
2099 SetPciConfig1(0x71, tmp8);*/
2101 /* Use MEMORY READ LINE for reads.
2102 * NOTE: Although not mentioned in the PCI0646U specs,
2103 * these bits are write only and won't be read
2104 * back as set or not. The PCI0646U2 specs clarify
2108 SetPciConfig1(0x71, tmp8);
2110 /* Set reasonable active/recovery/address-setup values. */
2111 SetPciConfig1(0x53, 0x40);
2112 SetPciConfig1(0x54, 0x3f);
2113 SetPciConfig1(0x55, 0x40);
2114 SetPciConfig1(0x56, 0x3f);
2115 SetPciConfig1(0x57, 0x1c);
2116 SetPciConfig1(0x58, 0x3f);
2117 SetPciConfig1(0x5b, 0x3f);
2124 if(c
== CHAN_NOT_SPECIFIED
) {
2130 ChangePciConfig1(0x52, (a
& ~0x04));
2134 ChangePciConfig1(0x49, (a
& ~0x01));
2137 ChangePciConfig2(0x50, (a
| 0x0008));
2138 ChangePciConfig2(0x52, (a
| 0x0008));
2141 ChangePciConfig2(0x04, (a
& ~0x0400));
2144 if(ChipType
== SIS133NEW
) {
2146 // check 80-pin cable
2147 if(c
== CHAN_NOT_SPECIFIED
) {
2150 chan
= &deviceExtension
->chan
[c
];
2151 GetPciConfig2(channel
? 0x52 : 0x50, tmp16
);
2152 if(tmp16
& 0x8000) {
2153 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2157 // check 80-pin cable
2158 if(c
== CHAN_NOT_SPECIFIED
) {
2161 chan
= &deviceExtension
->chan
[c
];
2162 GetPciConfig1(48, tmp8
);
2163 if(tmp8
& (0x10 << channel
)) {
2164 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2171 /* if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
2174 if(c
== CHAN_NOT_SPECIFIED
) {
2175 /* prepare for ATA-66 on the 82C686a and 82C596b */
2176 if(ChipFlags
& VIACLK
) {
2177 ChangePciConfig4(0x50, (a
| 0x030b030b));
2180 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2181 /* enable PCI interrupt */
2182 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a
& ~0x0400));
2185 * vt6420/1 has problems talking to some drives. The following
2186 * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
2188 * When host issues HOLD, device may send up to 20DW of data
2189 * before acknowledging it with HOLDA and the host should be
2190 * able to buffer them in FIFO. Unfortunately, some WD drives
2191 * send upto 40DW before acknowledging HOLD and, in the
2192 * default configuration, this ends up overflowing vt6421's
2193 * FIFO, making the controller abort the transaction with
2196 * Rx52[2] is the internal 128DW FIFO Flow control watermark
2197 * adjusting mechanism enable bit and the default value 0
2198 * means host will issue HOLD to device when the left FIFO
2199 * size goes below 32DW. Setting it to 1 makes the watermark
2202 * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
2205 if(DeviceID
== 0x3149 || DeviceID
== 0x3249) { //vt6420 or vt6421
2206 KdPrint2((PRINT_PREFIX
"VIA 642x FIFO\n"));
2207 ChangePciConfig1(0x52, a
| (1 << 2));
2213 /* the southbridge might need the data corruption fix */
2214 if(ChipFlags
& VIABUG
) {
2215 AtapiViaSouthBridgeFixup(HwDeviceExtension
, PCIConfiguration
,
2216 SystemIoBusNumber
, slotNumber
);
2218 /* set prefetch, postwrite */
2219 if(ChipType
!= VIA133
) {
2220 ChangePciConfig1(0x41, (a
| 0xf0));
2223 /* set fifo configuration half'n'half */
2224 ChangePciConfig1(0x43, ((a
& ((ChipFlags
& VIAPRQ
) ? 0x80 : 0x90)) | 0x2a));
2226 /* set status register read retry */
2227 ChangePciConfig1(0x44, (a
| 0x08));
2229 /* set DMA read & end-of-sector fifo flush */
2230 ChangePciConfig1(0x46, ((a
& 0x0c) | 0xf0));
2232 /* set sector size */
2233 SetPciConfig2(0x60, DEV_BSIZE
);
2234 SetPciConfig2(0x68, DEV_BSIZE
);
2237 chan
= &deviceExtension
->chan
[c
];
2239 if(ChipFlags
& (UNIATA_SATA
| VIASATA
)) {
2240 if((ChipFlags
& VIABAR
) && (c
>= 2)) {
2243 UniataSataWritePort4(chan
, IDX_SATA_SError
, 0xffffffff, 0);
2247 // check 80-pin cable
2248 if(!via_cable80(deviceExtension, channel)) {
2249 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
2257 if(ChipType
== ITE_33
|| ChipType
== ITE_133_NEW
) {
2260 if(ChipType
== ITE_133
) {
2261 if(c
== CHAN_NOT_SPECIFIED
) {
2262 /* set PCI mode and 66Mhz reference clock */
2263 ChangePciConfig1(0x50, a
& ~0x83);
2265 /* set default active & recover timings */
2266 SetPciConfig1(0x54, 0x31);
2267 SetPciConfig1(0x56, 0x31);
2269 // check 80-pin cable
2270 GetPciConfig2(0x40, tmp16
);
2271 chan
= &deviceExtension
->chan
[c
];
2272 if(!(tmp16
& (channel
? 0x08 : 0x04))) {
2273 chan
->MaxTransferMode
= min(deviceExtension
->MaxTransferMode
, ATA_UDMA2
);
2277 if(ChipType
== ITE_133_NEW
) {
2281 if(c
!= CHAN_NOT_SPECIFIED
) {
2282 // We don't know how to check for 80-pin cable on unknown controllers.
2283 // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
2284 // So, leave this flag to use as hint in error recovery procedures
2285 KdPrint2((PRINT_PREFIX
"UNIATA_NO80CHK\n"));
2286 deviceExtension
->HwFlags
|= UNIATA_NO80CHK
;
2291 // In all places separate channels are inited after common controller init
2292 // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
2293 if(CheckCable
&& !(ChipFlags
& (UNIATA_NO80CHK
| UNIATA_SATA
))) {
2294 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2295 AtapiChipInit(HwDeviceExtension
, DeviceNumber
, c
);
2300 } // end AtapiChipInit()
2305 IN PHW_DEVICE_EXTENSION deviceExtension
,
2306 IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0
,
2314 if(!BaseIoAddressBM_0
) {
2317 for(c
=0; c
<deviceExtension
->NumberChannels
; c
++) {
2318 chan
= &deviceExtension
->chan
[c
];
2319 for (i
=0; i
<IDX_BM_IO_SZ
; i
++) {
2320 chan
->RegTranslation
[IDX_BM_IO
+i
].Addr
= BaseIoAddressBM_0
? ((ULONGIO_PTR
)BaseIoAddressBM_0
+ i
) : 0;
2321 chan
->RegTranslation
[IDX_BM_IO
+i
].MemIo
= MemIo
;
2323 if(BaseIoAddressBM_0
) {
2324 BaseIoAddressBM_0
++;
2328 } // end UniataInitMapBM()
2333 IN PHW_CHANNEL chan
,
2334 IN PIDE_REGISTERS_1 BaseIoAddress1
,
2335 IN PIDE_REGISTERS_2 BaseIoAddress2
2340 for (i
=0; i
<IDX_IO1_SZ
; i
++) {
2341 chan
->RegTranslation
[IDX_IO1
+i
].Addr
= BaseIoAddress1
? ((ULONGIO_PTR
)BaseIoAddress1
+ i
) : 0;
2342 chan
->RegTranslation
[IDX_IO1
+i
].MemIo
= FALSE
;
2344 for (i
=0; i
<IDX_IO2_SZ
; i
++) {
2345 chan
->RegTranslation
[IDX_IO2
+i
].Addr
= BaseIoAddress2
? ((ULONGIO_PTR
)BaseIoAddress2
+ i
) : 0;
2346 chan
->RegTranslation
[IDX_IO2
+i
].MemIo
= FALSE
;
2348 UniataInitSyncBaseIO(chan
);
2350 } // end UniataInitMapBase()
2354 UniataInitSyncBaseIO(
2358 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO1_o
], &chan
->RegTranslation
[IDX_IO1
], IDX_IO1_SZ
*sizeof(chan
->RegTranslation
[0]));
2359 RtlCopyMemory(&chan
->RegTranslation
[IDX_IO2_o
], &chan
->RegTranslation
[IDX_IO2
], IDX_IO2_SZ
*sizeof(chan
->RegTranslation
[0]));
2361 } // end UniataInitSyncBaseIO()
2366 IN PHW_CHANNEL chan
,
2367 IN PHW_DEVICE_EXTENSION deviceExtension
,
2373 KdPrint2((PRINT_PREFIX
"AtapiSetupLunPtrs for channel %d of %d, %d luns \n", c
, deviceExtension
->NumberChannels
, deviceExtension
->NumberLuns
));
2375 if(!deviceExtension
->NumberLuns
) {
2376 KdPrint2((PRINT_PREFIX
"Achtung !deviceExtension->NumberLuns \n"));
2377 deviceExtension
->NumberLuns
= IDE_MAX_LUN_PER_CHAN
;
2379 KdPrint2((PRINT_PREFIX
" Chan %#x\n", chan
));
2380 chan
->DeviceExtension
= deviceExtension
;
2382 chan
->NumberLuns
= deviceExtension
->NumberLuns
;
2383 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2384 chan
->lun
[i
] = &(deviceExtension
->lun
[c
*deviceExtension
->NumberLuns
+i
]);
2385 KdPrint2((PRINT_PREFIX
" Lun %#x\n", i
));
2386 KdPrint2((PRINT_PREFIX
" Lun ptr %#x\n", chan
->lun
[i
]));
2388 chan
->AltRegMap
= deviceExtension
->AltRegMap
;
2389 chan
->NextDpcChan
= -1;
2390 for(i
=0; i
<deviceExtension
->NumberLuns
; i
++) {
2391 chan
->lun
[i
]->DeviceExtension
= deviceExtension
;
2392 chan
->lun
[i
]->chan
= chan
;
2393 chan
->lun
[i
]->Lun
= i
;
2395 if((deviceExtension
->HwFlags
& UNIATA_AHCI
) &&
2396 deviceExtension
->AhciInternalAtaReq0
&&
2397 deviceExtension
->AhciInternalSrb0
) {
2398 chan
->AhciInternalAtaReq
= &(deviceExtension
->AhciInternalAtaReq0
[c
]);
2399 chan
->AhciInternalSrb
= &(deviceExtension
->AhciInternalSrb0
[c
]);
2400 UniataAhciSetupCmdPtr(chan
->AhciInternalAtaReq
);
2401 chan
->AhciInternalSrb
->SrbExtension
= chan
->AhciInternalAtaReq
;
2402 chan
->AhciInternalAtaReq
->Srb
= chan
->AhciInternalSrb
;
2405 } // end AtapiSetupLunPtrs()
2409 UniataAllocateLunExt(
2410 PHW_DEVICE_EXTENSION deviceExtension
,
2411 ULONG NewNumberChannels
2414 PHW_LU_EXTENSION old_luns
= NULL
;
2415 PHW_CHANNEL old_chans
= NULL
;
2417 KdPrint2((PRINT_PREFIX
"allocate %d Luns for %d channels\n", deviceExtension
->NumberLuns
, deviceExtension
->NumberChannels
));
2419 old_luns
= deviceExtension
->lun
;
2420 old_chans
= deviceExtension
->chan
;
2422 if(old_luns
|| old_chans
) {
2423 if(NewNumberChannels
== UNIATA_ALLOCATE_NEW_LUNS
) {
2424 KdPrint2((PRINT_PREFIX
"already allocated!\n"));
2429 if(!deviceExtension
->NumberLuns
) {
2430 KdPrint2((PRINT_PREFIX
"default NumberLuns=2\n"));
2431 deviceExtension
->NumberLuns
= 2;
2434 if(deviceExtension
->HwFlags
& UNIATA_AHCI
) {
2435 if(!deviceExtension
->AhciInternalAtaReq0
) {
2436 deviceExtension
->AhciInternalAtaReq0
= (PATA_REQ
)ExAllocatePool(NonPagedPool
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2437 if (!deviceExtension
->AhciInternalAtaReq0
) {
2438 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalAtaReq0 => SP_RETURN_ERROR\n"));
2441 RtlZeroMemory(deviceExtension
->AhciInternalAtaReq0
, sizeof(ATA_REQ
)*deviceExtension
->NumberChannels
);
2443 if(!deviceExtension
->AhciInternalSrb0
) {
2444 deviceExtension
->AhciInternalSrb0
= (PSCSI_REQUEST_BLOCK
)ExAllocatePool(NonPagedPool
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2445 if (!deviceExtension
->AhciInternalSrb0
) {
2446 KdPrint2((PRINT_PREFIX
"!deviceExtension->AhciInternalSrb0 => SP_RETURN_ERROR\n"));
2447 UniataFreeLunExt(deviceExtension
);
2450 RtlZeroMemory(deviceExtension
->AhciInternalSrb0
, sizeof(SCSI_REQUEST_BLOCK
)*deviceExtension
->NumberChannels
);
2454 deviceExtension
->lun
= (PHW_LU_EXTENSION
)ExAllocatePool(NonPagedPool
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2455 if (!deviceExtension
->lun
) {
2456 KdPrint2((PRINT_PREFIX
"!deviceExtension->lun => SP_RETURN_ERROR\n"));
2457 UniataFreeLunExt(deviceExtension
);
2460 RtlZeroMemory(deviceExtension
->lun
, sizeof(HW_LU_EXTENSION
) * (deviceExtension
->NumberChannels
+1) * deviceExtension
->NumberLuns
);
2462 deviceExtension
->chan
= (PHW_CHANNEL
)ExAllocatePool(NonPagedPool
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2463 if (!deviceExtension
->chan
) {
2464 UniataFreeLunExt(deviceExtension
);
2465 KdPrint2((PRINT_PREFIX
"!deviceExtension->chan => SP_RETURN_ERROR\n"));
2468 RtlZeroMemory(deviceExtension
->chan
, sizeof(HW_CHANNEL
) * (deviceExtension
->NumberChannels
+1));
2470 } // end UniataAllocateLunExt()
2475 PHW_DEVICE_EXTENSION deviceExtension
2478 if (deviceExtension
->lun
) {
2479 ExFreePool(deviceExtension
->lun
);
2480 deviceExtension
->lun
= NULL
;
2482 if (deviceExtension
->chan
) {
2483 ExFreePool(deviceExtension
->chan
);
2484 deviceExtension
->chan
= NULL
;
2486 if(deviceExtension
->AhciInternalAtaReq0
) {
2487 ExFreePool(deviceExtension
->AhciInternalAtaReq0
);
2488 deviceExtension
->AhciInternalAtaReq0
= NULL
;
2490 if(deviceExtension
->AhciInternalSrb0
) {
2491 ExFreePool(deviceExtension
->AhciInternalSrb0
);
2492 deviceExtension
->AhciInternalSrb0
= NULL
;
2496 } // end UniataFreeLunExt()