ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

id_init.cpp
Go to the documentation of this file.
00001 /*++
00002 
00003 Copyright (c) 2004-2011 Alexandr A. Telyatnikov (Alter)
00004 
00005 Module Name:
00006     id_init.cpp
00007 
00008 Abstract:
00009     This is the chip-specific init module for ATA/ATAPI IDE controllers
00010     with Busmaster DMA and Serial ATA support
00011 
00012 Author:
00013     Alexander A. Telyatnikov (Alter)
00014 
00015 Environment:
00016     kernel mode only
00017 
00018 Notes:
00019 
00020     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00021     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00023     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00024     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00025     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00029     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 
00031 Revision History:
00032 
00033     Some parts of code were taken from FreeBSD 5.1-6.1 ATA driver by
00034         Søren Schmidt, Copyright (c) 1998-2007
00035     added IT8172 IDE controller support from Linux
00036     added VIA 8233/8235 fix from Linux
00037     added 80-pin cable detection from Linux for
00038         VIA, nVidia
00039     added support for non-standard layout of registers
00040     added SATA support
00041 
00042 --*/
00043 
00044 #include "stdafx.h"
00045 
00046 BOOLEAN
00047 NTAPI
00048 UniataChipDetectChannels(
00049     IN PVOID HwDeviceExtension,
00050     IN PPCI_COMMON_CONFIG pciData, // optional
00051     IN ULONG DeviceNumber,
00052     IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
00053     )
00054 {
00055     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
00056     //ULONG slotNumber = deviceExtension->slotNumber;
00057     //ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
00058     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
00059     //ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
00060     //ULONG RevID    =  deviceExtension->RevID;
00061     ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
00062     ULONG ChipFlags= deviceExtension->HwFlags & CHIPFLAG_MASK;
00063 
00064     KdPrint2((PRINT_PREFIX "UniataChipDetectChannels:\n" ));
00065 
00066     if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
00067         if(!deviceExtension->NumberChannels) {
00068             KdPrint2((PRINT_PREFIX "uninitialized SATA/AHCI port number -> 1\n"));
00069             deviceExtension->NumberChannels = 1;
00070         }
00071         if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhciPM", 1 /* DEBUG */)) {
00072             KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1\n"));
00073             deviceExtension->NumberLuns = 2;
00074             //chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00075         } else {
00076             KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
00077             deviceExtension->NumberLuns = SATA_MAX_PM_UNITS;
00078             //deviceExtension->NumberLuns = 1;
00079         }
00080     }
00081     if(deviceExtension->MasterDev) {
00082         KdPrint2((PRINT_PREFIX "MasterDev -> 1 chan\n"));
00083         deviceExtension->NumberChannels = 1;
00084     }
00085 
00086     switch(VendorID) {
00087     case ATA_ACER_LABS_ID:
00088         switch(deviceExtension->DevID) {
00089         case 0x528710b9:
00090         case 0x528810b9:
00091             deviceExtension->NumberChannels = 4;
00092             KdPrint2((PRINT_PREFIX "Acer 4 chan\n"));
00093         }
00094         break;
00095     case ATA_PROMISE_ID:
00096 
00097         if(ChipType != PRMIO) {
00098             break;
00099         }
00100         deviceExtension->NumberChannels = 4;
00101         KdPrint2((PRINT_PREFIX "Promise 4 chan\n"));
00102         break;
00103     case ATA_MARVELL_ID:
00104         KdPrint2((PRINT_PREFIX "Marvell\n"));
00105         switch(deviceExtension->DevID) {
00106         case 0x610111ab: 
00107             /* 88SX6101 only have 1 PATA channel */
00108             if(BMList[deviceExtension->DevIndex].channel) {
00109                 KdPrint2((PRINT_PREFIX "88SX6101 has no 2nd PATA chan\n"));
00110                 return FALSE;
00111             }
00112             deviceExtension->NumberChannels = 1;
00113             KdPrint2((PRINT_PREFIX "88SX6101 PATA 1 chan\n"));
00114             break;
00115         }
00116         break;
00117     case ATA_ATI_ID:
00118         KdPrint2((PRINT_PREFIX "ATI\n"));
00119         switch(deviceExtension->DevID) {
00120         case ATA_ATI_IXP600:    
00121         case ATA_ATI_IXP700:
00122             /* IXP600 & IXP700 only have 1 PATA channel */
00123             if(BMList[deviceExtension->DevIndex].channel) {
00124                 KdPrint2((PRINT_PREFIX "New ATI no 2nd PATA chan\n"));
00125                 return FALSE;
00126             }
00127             deviceExtension->NumberChannels = 1;
00128             KdPrint2((PRINT_PREFIX "New ATI PATA 1 chan\n"));
00129             break;
00130         }
00131         /* FALLTHROUGH */
00132     case ATA_SILICON_IMAGE_ID:
00133 
00134         if(ChipFlags & SIIBUG) {
00135         }
00136         if(ChipType != SIIMIO) {
00137             break;
00138         }
00139         if(!pciData) {
00140             break;
00141         }
00142 
00143         if(VendorID == ATA_SILICON_IMAGE_ID) {
00144             KdPrint2((PRINT_PREFIX "New SII\n"));
00145         } else {
00146             KdPrint2((PRINT_PREFIX "ATI SATA\n"));
00147         }
00148         if(deviceExtension->HwFlags & SII4CH) {
00149             deviceExtension->NumberChannels = 4;
00150             KdPrint2((PRINT_PREFIX "4 chan\n"));
00151         }
00152         break;
00153     case ATA_VIA_ID:
00154         if(/*(deviceExtension->DevID == 0x32491106) &&
00155            ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)*/
00156            deviceExtension->HwFlags & VIABAR) {
00157             deviceExtension->NumberChannels = 3;
00158             KdPrint2((PRINT_PREFIX "VIA 3 chan\n"));
00159         }
00160         if(ChipFlags & VIASATA) {
00161             /* 2 SATA without SATA registers on first channel + 1 PATA on second */
00162             // do nothing, generic PATA INIT
00163             KdPrint2((PRINT_PREFIX "VIA SATA without SATA regs -> no PM\n"));
00164             deviceExtension->NumberLuns = 1;
00165         }
00166         break;
00167     case ATA_ITE_ID:
00168         /* ITE ATA133 controller */
00169         if(deviceExtension->DevID == 0x82131283) { 
00170             if(BMList[deviceExtension->DevIndex].channel) {
00171                 KdPrint2((PRINT_PREFIX "New ITE has no 2nd PATA chan\n"));
00172                 return FALSE;
00173             }
00174             deviceExtension->NumberChannels = 1;
00175             KdPrint2((PRINT_PREFIX "New ITE PATA 1 chan\n"));
00176         }
00177         break;
00178     case ATA_INTEL_ID:
00179         /* New Intel PATA controllers */
00180         if(/*deviceExtension->DevID == 0x27df8086 ||
00181            deviceExtension->DevID == 0x269e8086 ||
00182            deviceExtension->DevID == ATA_I82801HBM*/
00183            ChipFlags & I1CH) { 
00184             if(BMList[deviceExtension->DevIndex].channel) {
00185                 KdPrint2((PRINT_PREFIX "New Intel PATA has no 2nd chan\n"));
00186                 return FALSE;
00187             }
00188             deviceExtension->NumberChannels = 1;
00189             KdPrint2((PRINT_PREFIX "New Intel PATA 1 chan\n"));
00190         }
00191         break;
00192     case ATA_JMICRON_ID:
00193         /* New JMicron PATA controllers */
00194         if(deviceExtension->DevID == ATA_JMB361 ||
00195            deviceExtension->DevID == ATA_JMB363 ||
00196            deviceExtension->DevID == ATA_JMB368) { 
00197             if(BMList[deviceExtension->DevIndex].channel) {
00198                 KdPrint2((PRINT_PREFIX "New JMicron has no 2nd chan\n"));
00199                 return FALSE;
00200             }
00201             deviceExtension->NumberChannels = 1;
00202             KdPrint2((PRINT_PREFIX "New JMicron PATA 1 chan\n"));
00203         }
00204         break;
00205     } // end switch(VendorID)
00206     return TRUE;
00207 
00208 } // end UniataChipDetectChannels()
00209 
00210 NTSTATUS
00211 NTAPI
00212 UniataChipDetect(
00213     IN PVOID HwDeviceExtension,
00214     IN PPCI_COMMON_CONFIG pciData, // optional
00215     IN ULONG DeviceNumber,
00216     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
00217     IN BOOLEAN* simplexOnly
00218     )
00219 {
00220     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
00221     ULONG slotNumber = deviceExtension->slotNumber;
00222     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
00223     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
00224     ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
00225     ULONG RevID    =  deviceExtension->RevID;
00226     ULONG i, c;
00227     BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
00228     PHW_CHANNEL chan;
00229     ULONG ChipType;
00230     ULONG ChipFlags;
00231     ULONG tmp32;
00232     UCHAR tmp8;
00233     ULONG BaseMemAddress;
00234     ULONG BaseIoAddress1;
00235     ULONG BaseIoAddress2;
00236     ULONG BaseIoAddressBM;
00237     BOOLEAN MemIo = FALSE;
00238 
00239     KdPrint2((PRINT_PREFIX "UniataChipDetect:\n" ));
00240     KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
00241 
00242     i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[0], VendorID, 0xffff, 0, NUM_BUSMASTER_ADAPTERS);
00243 
00244     c = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", 0);
00245     if(c) {
00246         *simplexOnly = TRUE;
00247     }
00248 
00249     // defaults
00250     BaseIoAddressBM = pciData->u.type0.BaseAddresses[4] & ~0x07;
00251     deviceExtension->MaxTransferMode = BaseIoAddressBM ? ATA_DMA : ATA_PIO4;
00252     ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
00253     deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
00254 
00255     KdPrint2((PRINT_PREFIX "i: %#x\n", i));
00256     if(i != BMLIST_TERMINATOR) {
00257         DevTypeInfo = (PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[i];
00258     } else {
00259         if(Ata_is_ahci_dev(pciData)) {
00260             KdPrint2((PRINT_PREFIX "  AHCI candidate"));
00261 
00262             deviceExtension->NumberChannels = 0;
00263             if(!UniataAhciDetect(HwDeviceExtension, pciData, ConfigInfo)) {
00264                 KdPrint2((PRINT_PREFIX "  AHCI init failed - not detected\n"));
00265                 return STATUS_UNSUCCESSFUL;
00266             }
00267             KdPrint2((PRINT_PREFIX "  unknown AHCI dev, addr %#x", deviceExtension->BaseIoAHCI_0.Addr));
00268         }
00269 unknown_dev:
00270         KdPrint2((PRINT_PREFIX "  unknown dev, BM addr %#I64x", BaseIoAddressBM));
00271         DevTypeInfo = NULL;
00272         KdPrint2((PRINT_PREFIX "  MaxTransferMode %#x\n", deviceExtension->MaxTransferMode));
00273 
00274         if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) {
00275             return STATUS_UNSUCCESSFUL;
00276         }
00277         if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
00278             return STATUS_UNSUCCESSFUL;
00279         }
00280 
00281         return STATUS_NOT_FOUND;
00282     }
00283 
00284     static BUSMASTER_CONTROLLER_INFORMATION const SiSAdapters[] = {
00285         PCI_DEV_HW_SPEC_BM( 0182, 1039, 0x00, ATA_SA150, "SiS 182"  , SISSATA   | UNIATA_SATA),
00286         PCI_DEV_HW_SPEC_BM( 0181, 1039, 0x00, ATA_SA150, "SiS 181"  , SISSATA   | UNIATA_SATA),
00287         PCI_DEV_HW_SPEC_BM( 0180, 1039, 0x00, ATA_SA150, "SiS 180"  , SISSATA   | UNIATA_SATA),
00288         PCI_DEV_HW_SPEC_BM( 0965, 1039, 0x00, ATA_UDMA6, "SiS 965"  , SIS133NEW        ),
00289         PCI_DEV_HW_SPEC_BM( 0964, 1039, 0x00, ATA_UDMA6, "SiS 964"  , SIS133NEW        ),
00290         PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6, "SiS 963"  , SIS133NEW        ),
00291         PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6, "SiS 962"  , SIS133NEW        ),
00292 
00293         PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5, "SiS 745"  , SIS100NEW        ),
00294         PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5, "SiS 735"  , SIS100NEW        ),
00295         PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5, "SiS 733"  , SIS100NEW        ),
00296         PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5, "SiS 730"  , SIS100OLD        ),
00297 
00298         PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6, "SiS 645DX", SIS133NEW        ),
00299 /*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),*/
00300 /*        PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640"  , SIS_SOUTH        ),*/
00301         PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5, "SiS 635"  , SIS100NEW        ),
00302         PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5, "SiS 633"  , SIS100NEW        ),
00303         PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5, "SiS 630S" , SIS100OLD        ),
00304         PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4, "SiS 630"  , SIS66            ),
00305         PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4, "SiS 620"  , SIS66            ),
00306 
00307         PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5, "SiS 550"  , SIS66            ),
00308         PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4, "SiS 540"  , SIS66            ),
00309         PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4, "SiS 530"  , SIS66            ),
00310 
00311 //        PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x04, ATA_UDMA6, "SiS 962L" , SIS133OLD        ), // ???
00312 //        PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_UDMA6, "SiS 961"  , SIS133OLD        ),
00313 
00314         PCI_DEV_HW_SPEC_BM( 5517, 1039, 0x00, ATA_UDMA5, "SiS 961"  , SIS100NEW | SIS_BASE ),
00315         PCI_DEV_HW_SPEC_BM( 5518, 1039, 0x00, ATA_UDMA6, "SiS 962/3", SIS133NEW | SIS_BASE ),
00316         PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2, "SiS 5513" , SIS33 | SIS_BASE ),
00317         PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2, "SiS 5513" , SIS33 | SIS_BASE ),
00318         PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_UDMA2, "SiS 5513" , SIS33 | SIS_BASE ),
00319         PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR       , NULL       , BMLIST_TERMINATOR )
00320         };
00321 
00322     static BUSMASTER_CONTROLLER_INFORMATION const ViaAdapters[] = {
00323         PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2, "VIA 82C586B", VIA33  | 0x00   ),
00324         PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2, "VIA 82C586B", VIA33  | VIAPRQ ),
00325         PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2, "VIA 82C586B", VIA33  | 0x00   ),
00326         PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2, "VIA 82C586" , VIA33  | 0x00   ),
00327         PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4, "VIA 82C596B", VIA66  | VIACLK ),
00328         PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2, "VIA 82C596" , VIA33  | 0x00   ),
00329         PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5, "VIA 82C686B", VIA100 | VIABUG ),
00330         PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4, "VIA 82C686A", VIA66  | VIACLK ),
00331         PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2, "VIA 82C686" , VIA33  | 0x00   ),
00332         PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5, "VIA 8231"   , VIA100 | VIABUG ),
00333         PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5, "VIA 8233"   , VIA100 | 0x00   ),
00334         PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5, "VIA 8233C"  , VIA100 | 0x00   ),
00335         PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6, "VIA 8233A"  , VIA133 | 0x00 ),
00336         PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6, "VIA 8235"   , VIA133 | 0x00 ),
00337         PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6, "VIA 8237"   , VIA133 | 0x00 ),
00338         PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6, "VIA 8237A"  , VIA133 | 0x00 ),
00339         // presence of AHCI controller means something about isa-mapped part
00340         PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_UDMA6, "VIA 8237S"  , VIA133 | 0x00 ),
00341         PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6, "VIA 8237"   , VIA133 | 0x00 ),
00342         PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6, "VIA 8237"   , VIA133 | 0x00 ),
00343         PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6, "VIA 8251"   , VIA133 | 0x00 ),
00344         PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150, "VIA CX700"  , VIA133 | VIASATA),
00345         PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150, "VIA VX800"  , VIA133 | VIASATA),
00346         PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6, "VIA VX855"  , VIA133 | 0x00 ),
00347         PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300, "VIA VX900"  , VIA133 | VIASATA),
00348         PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR       , NULL         , BMLIST_TERMINATOR )
00349         };
00350 
00351     static BUSMASTER_CONTROLLER_INFORMATION const ViaSouthAdapters[] = {
00352         PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, -1, "VIA 8361", VIASOUTH ),
00353         PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, -1, "VIA 8363", VIASOUTH ),
00354         PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, -1, "VIA 8371", VIASOUTH ),
00355         PCI_DEV_HW_SPEC_BM( 3102, 1106, 0x00, -1, "VIA 8662", VIASOUTH ),
00356         PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR, NULL      , BMLIST_TERMINATOR )
00357         };
00358 
00359     KdPrint2((PRINT_PREFIX "VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID, DeviceID, RevID));
00360 
00361     switch(VendorID) {
00362 
00363     case ATA_SIS_ID:
00364         KdPrint2((PRINT_PREFIX "ATA_SIS_ID\n"));
00365         DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&SiSAdapters[0];
00366         i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
00367         if(i != BMLIST_TERMINATOR) {
00368             deviceExtension->FullDevName = SiSAdapters[i].FullDevName;
00369         }
00370         goto for_ugly_chips;
00371 
00372     case ATA_VIA_ID: 
00373         KdPrint2((PRINT_PREFIX "ATA_VIA_ID\n"));
00374         // New chips have own DeviceId
00375         if(deviceExtension->DevID != ATA_VIA82C571 &&
00376            deviceExtension->DevID != ATA_VIACX700IDE &&
00377            deviceExtension->DevID != ATA_VIASATAIDE &&
00378            deviceExtension->DevID != ATA_VIASATAIDE2 &&
00379            deviceExtension->DevID != ATA_VIASATAIDE3) {
00380             KdPrint2((PRINT_PREFIX "Via new\n"));
00381             break;
00382         }
00383         KdPrint2((PRINT_PREFIX "Via-old-style %x\n", deviceExtension->DevID));
00384         // Traditionally, chips have same DeviceId, we can distinguish between them
00385         // only by ISA Bridge DeviceId
00386         DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaSouthAdapters[0];
00387         i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber,
00388                                PCISLOTNUM_NOT_SPECIFIED/*slotNumber*/, NULL);
00389 /*        if(i == BMLIST_TERMINATOR) {
00390             i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
00391         }*/
00392         if(i != BMLIST_TERMINATOR) {
00393             KdPrint2((PRINT_PREFIX "VIASOUTH\n"));
00394             deviceExtension->HwFlags |= VIASOUTH;
00395         }
00396         DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaAdapters[0];
00397         i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber,
00398                                PCISLOTNUM_NOT_SPECIFIED/*slotNumber*/, NULL);
00399         if(i != BMLIST_TERMINATOR) {
00400             deviceExtension->FullDevName = ViaAdapters[i].FullDevName;
00401         }
00402         goto for_ugly_chips;
00403 
00404     default:
00405 
00406         // do nothing
00407         break;
00408 
00409 #if 0
00410         KdPrint2((PRINT_PREFIX "Default\n"));
00411 
00412         deviceExtension->MaxTransferMode = deviceExtension->BaseIoAddressBM_0 ? ATA_DMA : ATA_PIO4;
00413         /* do extra chipset specific setups */
00414         switch(deviceExtension->DevID) {
00415 
00416       //case ATA_CYPRESS_ID:
00417         case 0xc6931080:         /* 82c693 ATA controller */
00418             deviceExtension->MaxTransferMode = ATA_WDMA2;
00419             break;
00420 
00421         case 0x000116ca:         /* Cenatek Rocket Drive controller */
00422             deviceExtension->MaxTransferMode = ATA_WDMA2;
00423             break;
00424 
00425 /*      case ATA_CYRIX_ID:
00426             DevTypeInfo = &CyrixAdapters[0];
00427             break;*/
00428         case 0x01021078:        /* Cyrix 5530 ATA33 controller */
00429             deviceExtension->MaxTransferMode = ATA_UDMA2;
00430             break;
00431 
00432         case 0x06401039:        /* CMD 640 known bad, no DMA */
00433         case 0x06011039:
00434             *simplexOnly = TRUE; 
00435 
00436             /* FALLTHROUGH */
00437 
00438         case 0x10001042:        /* RZ 100x known bad, no DMA */
00439         case 0x10011042:
00440 
00441             if(deviceExtension->BaseIoAddressBM_0)
00442                 ScsiPortFreeDeviceBase(HwDeviceExtension,
00443                                        deviceExtension->BaseIoAddressBM_0);
00444 
00445             deviceExtension->BaseIoAddressBM_0 = 0;
00446             deviceExtension->BusMaster = FALSE;
00447             deviceExtension->MaxTransferMode = ATA_PIO4;
00448             break;
00449 
00450         case 0x81721283:        /* IT8172 IDE controller */
00451             deviceExtension->MaxTransferMode = ATA_UDMA2;
00452             *simplexOnly = TRUE; 
00453             break;
00454 
00455         default:
00456             return STATUS_NOT_FOUND;
00457         }
00458         return STATUS_SUCCESS;
00459 #endif
00460     }
00461 
00462     i = Ata_is_dev_listed(DevTypeInfo, VendorID, DeviceID, RevID, -1);
00463 for_ugly_chips:
00464     KdPrint2((PRINT_PREFIX "i: %#x\n", i));
00465     if(i == BMLIST_TERMINATOR) {
00466         goto unknown_dev;
00467         //return STATUS_NOT_FOUND;
00468     }
00469     deviceExtension->MaxTransferMode =  DevTypeInfo[i].MaxTransferMode;
00470     deviceExtension->HwFlags         |= DevTypeInfo[i].RaidFlags;
00471 
00472     KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
00473 
00474     tmp32 = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"HwFlagsOverride", deviceExtension->HwFlags);
00475     KdPrint2((PRINT_PREFIX "HwFlagsOverride: %#x\n", tmp32));
00476     deviceExtension->HwFlags = tmp32;
00477 
00478     tmp32 = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"HwFlagsAdd", 0);
00479     KdPrint2((PRINT_PREFIX "HwFlagsAdd: %#x\n", tmp32));
00480     deviceExtension->HwFlags |= tmp32;
00481 
00482     KdPrint2((PRINT_PREFIX "HwFlags (final): %#x\n", deviceExtension->HwFlags));
00483     if(deviceExtension->HwFlags & UNIATA_SIMPLEX_ONLY) {
00484         KdPrint2((PRINT_PREFIX "UNIATA_SIMPLEX_ONLY\n" ));
00485         *simplexOnly = TRUE;
00486     }
00487 
00488     KdPrint2((PRINT_PREFIX "MaxTransferMode: %#x\n", deviceExtension->MaxTransferMode));
00489     tmp32 = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", deviceExtension->MaxTransferMode);
00490     if(tmp32 != 0xffffffff) {
00491         KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", deviceExtension->MaxTransferMode));
00492         deviceExtension->MaxTransferMode = tmp32;
00493     }
00494 
00495     if(deviceExtension->MaxTransferMode >= ATA_SA150) {
00496         deviceExtension->HwFlags |= UNIATA_SATA;
00497     }
00498 /*
00499     ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
00500     deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
00501 */
00502     ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
00503     ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
00504 
00505     if(ChipFlags & UNIATA_AHCI) {
00506         deviceExtension->NumberChannels = 0;
00507         if(!UniataAhciDetect(HwDeviceExtension, pciData, ConfigInfo)) {
00508             KdPrint2((PRINT_PREFIX "  AHCI detect failed\n"));
00509             return STATUS_UNSUCCESSFUL;
00510         }
00511     } else
00512     if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) {
00513         return STATUS_UNSUCCESSFUL;
00514     }
00515     // UniataAhciDetect() sets proper number of channels
00516     if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
00517         return STATUS_UNSUCCESSFUL;
00518     }
00519 
00520     if(ChipFlags & UNIATA_AHCI) {
00521     }
00522 
00523     switch(VendorID) {
00524     case ATA_ACER_LABS_ID:
00525         if(ChipFlags & UNIATA_SATA) {
00526             deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
00527             BaseIoAddress1  = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00528                                     0, 0, 0x10);
00529             BaseIoAddress2  = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00530                                     1, 0, 0x10);
00531             BaseIoAddressBM = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00532                                     4, 0, deviceExtension->NumberChannels*sizeof(IDE_BUSMASTER_REGISTERS));
00533             for(c=0; c<deviceExtension->NumberChannels; c++) {
00534                 //ULONG unit01 = (c & 1);
00535                 ULONG unit10 = (c & 2);
00536                 chan = &deviceExtension->chan[c];
00537 
00538                 for (i=0; i<=IDX_IO1_SZ; i++) {
00539                     chan->RegTranslation[IDX_IO1+i].Addr           = BaseIoAddress1  + i + (unit10 ? 8 : 0);
00540                 }
00541                 chan->RegTranslation[IDX_IO2_AltStatus].Addr       = BaseIoAddress2  + 2 + (unit10 ? 4 : 0);
00542                 UniataInitSyncBaseIO(chan);
00543 
00544                 for (i=0; i<=IDX_BM_IO_SZ; i++) {
00545                     chan->RegTranslation[IDX_BM_IO+i].Addr         = BaseIoAddressBM + i + (c * sizeof(IDE_BUSMASTER_REGISTERS));
00546                 }
00547 
00548                 // SATA not supported yet
00549 
00550                 //chan->RegTranslation[IDX_BM_Command]          = BaseMemAddress + 0x260 + offs7;
00551                 //chan->RegTranslation[IDX_BM_PRD_Table]        = BaseMemAddress + 0x244 + offs7;
00552                 //chan->RegTranslation[IDX_BM_DeviceSpecific0]  = BaseMemAddress + (c << 2);
00553 
00554                 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00555             }
00556         }
00557         break;
00558     case ATA_NVIDIA_ID:
00559         if(ChipFlags & UNIATA_SATA) {
00560             KdPrint2((PRINT_PREFIX "NVIDIA SATA\n"));
00561             BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00562                                     5, 0, ((ChipFlags & NV4OFF) ? 0x400 : 0) + 0x40*2);
00563             KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
00564             if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
00565                 KdPrint2((PRINT_PREFIX "MemIo\n"));
00566                 MemIo = TRUE;
00567             }
00568             deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
00569             deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
00570             for(c=0; c<deviceExtension->NumberChannels; c++) {
00571                 chan = &deviceExtension->chan[c];
00572 
00573                 chan->RegTranslation[IDX_SATA_SStatus].Addr   = BaseMemAddress +     (c << 6);
00574                 chan->RegTranslation[IDX_SATA_SStatus].MemIo  = MemIo;
00575                 chan->RegTranslation[IDX_SATA_SError].Addr    = BaseMemAddress + 4 + (c << 6);
00576                 chan->RegTranslation[IDX_SATA_SError].MemIo   = MemIo;
00577                 chan->RegTranslation[IDX_SATA_SControl].Addr  = BaseMemAddress + 8 + (c << 6);
00578                 chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
00579 
00580                 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00581             }
00582         }
00583         break;
00584     case ATA_PROMISE_ID:
00585 
00586         if(ChipType != PRMIO) {
00587             break;
00588         }
00589         if(!pciData) {
00590             break;
00591         }
00592         deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
00593         BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00594                                 4, 0, 0x4000);
00595         KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
00596         if((*ConfigInfo->AccessRanges)[4].RangeInMemory) {
00597             KdPrint2((PRINT_PREFIX "MemIo\n"));
00598             MemIo = TRUE;
00599         }
00600         deviceExtension->BaseIoAddressBM_0.Addr  = BaseMemAddress;
00601         deviceExtension->BaseIoAddressBM_0.MemIo = MemIo;
00602         for(c=0; c<deviceExtension->NumberChannels; c++) {
00603 
00604             ULONG offs12, offs7;
00605 
00606             chan = &deviceExtension->chan[c];
00607 
00608             offs12 = c << 12;
00609             offs7  = c << 7;
00610 
00611             for (i=0; i<=IDX_IO1_SZ; i++) {
00612                 chan->RegTranslation[IDX_IO1+i].Addr           = BaseMemAddress + 0x200 + (i << 2) + offs12;
00613                 chan->RegTranslation[IDX_IO1+i].MemIo          = MemIo;
00614             }
00615             chan->RegTranslation[IDX_IO2_AltStatus].Addr       = BaseMemAddress + 0x238 + offs7;
00616             chan->RegTranslation[IDX_IO2_AltStatus].MemIo      = MemIo;
00617 
00618             UniataInitSyncBaseIO(chan);
00619 
00620             chan->RegTranslation[IDX_BM_Command].Addr          = BaseMemAddress + 0x260 + offs7;
00621             chan->RegTranslation[IDX_BM_Command].MemIo         = MemIo;
00622             chan->RegTranslation[IDX_BM_PRD_Table].Addr        = BaseMemAddress + 0x244 + offs7;
00623             chan->RegTranslation[IDX_BM_PRD_Table].MemIo       = MemIo;
00624             chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr  = BaseMemAddress + (c << 2);
00625             chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
00626         }
00627         break;
00628 
00629     case ATA_ATI_ID:
00630         KdPrint2((PRINT_PREFIX "ATI\n"));
00631         /* FALLTHROUGH */
00632     case ATA_SILICON_IMAGE_ID: {
00633 
00634         if(ChipFlags & SIIBUG) {
00635         }
00636         if(ChipType != SIIMIO) {
00637             break;
00638         }
00639         if(!pciData) {
00640             break;
00641         }
00642 
00643         if(VendorID == ATA_SILICON_IMAGE_ID) {
00644             KdPrint2((PRINT_PREFIX "New SII\n"));
00645         } else {
00646             KdPrint2((PRINT_PREFIX "ATI SATA\n"));
00647         }
00648         //if(deviceExtension->HwFlags & SII4CH) {
00649             deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
00650         //}
00651         BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00652                                 5, 0, 0x800);
00653         KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
00654         if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
00655             KdPrint2((PRINT_PREFIX "MemIo\n"));
00656             MemIo = TRUE;
00657         }
00658         deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
00659         deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
00660 
00661         for(c=0; c<deviceExtension->NumberChannels; c++) {
00662             ULONG unit01 = (c & 1);
00663             ULONG unit10 = (c & 2);
00664 
00665             chan = &deviceExtension->chan[c];
00666 
00667             if(deviceExtension->AltRegMap) {
00668                 for (i=0; i<=IDX_IO1_SZ; i++) {
00669                     chan->RegTranslation[IDX_IO1+i].Addr           = BaseMemAddress + 0x80 + i + (unit01 << 6) + (unit10 << 8);
00670                     chan->RegTranslation[IDX_IO1+i].MemIo          = MemIo;
00671                 }
00672                 chan->RegTranslation[IDX_IO2_AltStatus].Addr       = BaseMemAddress + 0x8a + (unit01 << 6) + (unit10 << 8);
00673                 chan->RegTranslation[IDX_IO2_AltStatus].MemIo      = MemIo;
00674                 UniataInitSyncBaseIO(chan);
00675 
00676                 chan->RegTranslation[IDX_BM_Command].Addr          = BaseMemAddress + 0x00 + (unit01 << 3) + (unit10 << 8);
00677                 chan->RegTranslation[IDX_BM_Command].MemIo         = MemIo;
00678                 chan->RegTranslation[IDX_BM_Status].Addr           = BaseMemAddress + 0x02 + (unit01 << 3) + (unit10 << 8);
00679                 chan->RegTranslation[IDX_BM_Status].MemIo          = MemIo;
00680                 chan->RegTranslation[IDX_BM_PRD_Table].Addr        = BaseMemAddress + 0x04 + (unit01 << 3) + (unit10 << 8);
00681                 chan->RegTranslation[IDX_BM_PRD_Table].MemIo       = MemIo;
00682                 //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr  = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8);
00683                 //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
00684                 chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr  = BaseMemAddress + 0x10 + (unit01 << 3) + (unit10 << 8);
00685                 chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo;
00686                 chan->RegTranslation[IDX_BM_DeviceSpecific1].Addr  = BaseMemAddress + 0x40 + (unit01 << 2) + (unit10 << 8);
00687                 chan->RegTranslation[IDX_BM_DeviceSpecific1].MemIo = MemIo;
00688             }
00689 
00690             if(ChipFlags & UNIATA_SATA) {
00691                 chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + 0x104 + (unit01 << 7) + (unit10 << 8);
00692                 chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
00693                 chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + 0x108 + (unit01 << 7) + (unit10 << 8);
00694                 chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
00695                 chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + 0x100 + (unit01 << 7) + (unit10 << 8);
00696                 chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
00697 
00698                 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00699             }
00700         }
00701         break; }
00702 
00703     case ATA_SERVERWORKS_ID: {
00704 
00705         if(ChipType != SWKSMIO) {
00706             break;
00707         }
00708         if(!pciData) {
00709             break;
00710         }
00711 
00712         KdPrint2((PRINT_PREFIX "ServerWorks\n"));
00713 
00714         deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
00715         BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00716                                 5, 0, 0x400);
00717         KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
00718         if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
00719             KdPrint2((PRINT_PREFIX "MemIo\n"));
00720             MemIo = TRUE;
00721         }
00722         deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
00723         deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
00724 
00725         for(c=0; c<deviceExtension->NumberChannels; c++) {
00726             ULONG offs = c*0x100;
00727 
00728             chan = &deviceExtension->chan[c];
00729             for (i=0; i<=IDX_IO1_SZ; i++) {
00730                 chan->RegTranslation[IDX_IO1+i].Addr           = BaseMemAddress + offs + i*4;
00731                 chan->RegTranslation[IDX_IO1+i].MemIo          = MemIo;
00732             }
00733             chan->RegTranslation[IDX_IO2_AltStatus].Addr       = BaseMemAddress + offs + 0x20;
00734             chan->RegTranslation[IDX_IO2_AltStatus].MemIo      = MemIo;
00735             UniataInitSyncBaseIO(chan);
00736 
00737             chan->RegTranslation[IDX_BM_Command].Addr          = BaseMemAddress + offs + 0x30;
00738             chan->RegTranslation[IDX_BM_Command].MemIo         = MemIo;
00739             chan->RegTranslation[IDX_BM_Status].Addr           = BaseMemAddress + offs + 0x32;
00740             chan->RegTranslation[IDX_BM_Status].MemIo          = MemIo;
00741             chan->RegTranslation[IDX_BM_PRD_Table].Addr        = BaseMemAddress + offs + 0x34;
00742             chan->RegTranslation[IDX_BM_PRD_Table].MemIo       = MemIo;
00743 
00744             chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + offs + 0x40;
00745             chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;               
00746             chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + offs + 0x44;
00747             chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;               
00748             chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + offs + 0x48;
00749             chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
00750 
00751             chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00752         }
00753         break; }
00754 
00755     case ATA_SIS_ID: {
00756         //if(ChipType != SIS_SOUTH) {}
00757         BOOLEAN SIS_182=FALSE;
00758 
00759         if(!(ChipFlags & SIS_BASE)) {
00760             KdPrint2((PRINT_PREFIX "Found SIS_SOUTH\n"));
00761             //PrintNtConsole("Found SIS_SOUTH\n");
00762             break;
00763         }
00764         // Make some additional checks
00765         KdPrint2((PRINT_PREFIX "ChipType == SIS_BASE\n"));
00766         ChangePciConfig1(0x57, (a & 0x7f));
00767         GetPciConfig4(0x00, tmp32);
00768         if(tmp32 == ATA_SIS5518) {
00769             ChipType = SIS133NEW;
00770             deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133NEW;
00771             deviceExtension->MaxTransferMode = ATA_UDMA6;
00772             KdPrint2((PRINT_PREFIX "UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode));
00773             //PrintNtConsole("UniataChipDetect: SiS 962/963 DMA %#x controller\n", deviceExtension->MaxTransferMode);
00774             // Restore device ID
00775             ChangePciConfig1(0x57, (a | 0x80));
00776         } else {
00777             static BUSMASTER_CONTROLLER_INFORMATION const SiSSouthAdapters[] = {
00778                 PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, -1, "SiS 961", 0 ),
00779 //                PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, -1, "SiS 961", 0 ),
00780                 PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, -1, NULL     , -1 )
00781                 };
00782             // Save settings
00783             GetPciConfig1(0x4a, tmp8);
00784             ChangePciConfig1(0x4a, (a | 0x10));
00785             if(tmp32 == ATA_SIS5513 ||
00786                tmp32 == ATA_SIS5517) {
00787                 i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION*)&SiSSouthAdapters[0],
00788                      -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL); 
00789                 if(i != BMLIST_TERMINATOR) {
00790                     deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD;
00791                     //deviceExtension->MaxTransferMode = ATA_UDMA6;
00792                     deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
00793                     if(SiSSouthAdapters[i].RaidFlags & UNIATA_SATA) {
00794                         deviceExtension->HwFlags |= UNIATA_SATA;
00795                         if(SiSSouthAdapters[i].nDeviceId == 0x1182) {
00796                             SIS_182 = TRUE;
00797                         }
00798                     }
00799                 } else {
00800                     // SiS-South not found
00801                     if(tmp32 == ATA_SIS5517) {
00802                         deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS100NEW;
00803                         deviceExtension->MaxTransferMode = ATA_UDMA5;
00804                     } else {
00805                         // generic SiS33
00806                         KdPrint2((PRINT_PREFIX "Generic SiS DMA\n"));
00807                     }
00808                 }
00809             }
00810             // Restore settings
00811             SetPciConfig1(0x4a, tmp8);
00812             KdPrint2((PRINT_PREFIX "UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode));
00813             //PrintNtConsole("UniataChipDetect: SiS 961 DMA %#x controller\n", deviceExtension->MaxTransferMode);
00814             if(deviceExtension->HwFlags & UNIATA_SATA) {
00815                 KdPrint2((PRINT_PREFIX "SiS SATA\n"));
00816 
00817                 BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00818                                         5, 0, 0x400);
00819                 KdPrint2((PRINT_PREFIX "BaseMemAddress %x\n", BaseMemAddress));
00820                 if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
00821                     KdPrint2((PRINT_PREFIX "MemIo\n"));
00822                     MemIo = TRUE;
00823                 }
00824                 deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
00825                 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
00826 
00827                 for(c=0; c<deviceExtension->NumberChannels; c++) {
00828                     ULONG offs = c << (SIS_182 ? 5 : 6);
00829 
00830                     chan = &deviceExtension->chan[c];
00831                     chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + 0 + offs;
00832                     chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
00833                     chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + 4 + offs;
00834                     chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
00835                     chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + 8 + offs;
00836                     chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
00837 
00838                     chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00839                 }
00840             }
00841         }
00842         //ChangePciConfig1(0x57, (a | 0x80));
00843         break; }
00844 
00845     case ATA_VIA_ID: {
00846 
00847         if(ChipFlags & VIASATA) {
00848             /* 2 SATA without SATA registers on first channel + 1 PATA on second */
00849             // do nothing, generic PATA INIT
00850             KdPrint2((PRINT_PREFIX "VIA SATA without SATA regs\n"));
00851             break;
00852         }
00853         if(ChipFlags & UNIATA_SATA) {
00854 
00855             ULONG IoSize = 0;
00856             ULONG BaseMemAddress = 0;
00857 
00858             /*
00859              * vt6420/1 has problems talking to some drives.  The following
00860              * is based on the fix from Joseph Chan <JosephChan@via.com.tw>.
00861              *
00862              * When host issues HOLD, device may send up to 20DW of data
00863              * before acknowledging it with HOLDA and the host should be
00864              * able to buffer them in FIFO.  Unfortunately, some WD drives
00865              * send upto 40DW before acknowledging HOLD and, in the
00866              * default configuration, this ends up overflowing vt6421's
00867              * FIFO, making the controller abort the transaction with
00868              * R_ERR.
00869              *
00870              * Rx52[2] is the internal 128DW FIFO Flow control watermark
00871              * adjusting mechanism enable bit and the default value 0
00872              * means host will issue HOLD to device when the left FIFO
00873              * size goes below 32DW.  Setting it to 1 makes the watermark
00874              * 64DW.
00875              *
00876              * http://www.reactos.org/bugzilla/show_bug.cgi?id=6500
00877              */
00878 
00879             if(DeviceID == 0x3149 || DeviceID == 0x3249) {    //vt6420 or vt6421
00880                 KdPrint2((PRINT_PREFIX "VIA 642x FIFO\n"));
00881                 ChangePciConfig1(0x52, a | (1 << 2));
00882             }
00883 
00884             switch(DeviceID) {
00885             case 0x3149: // VIA 6420
00886                 KdPrint2((PRINT_PREFIX "VIA 6420\n"));
00887                 IoSize = 0x80;
00888                 break;
00889             case 0x3249: // VIA 6421
00890                 KdPrint2((PRINT_PREFIX "VIA 6421\n"));
00891                 IoSize = 0x40;
00892                 break;
00893             }
00894             if(IoSize) {
00895                 KdPrint2((PRINT_PREFIX "IoSize %x\n", IoSize));
00896                 /*deviceExtension->*/BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00897                                         5, 0, IoSize * deviceExtension->NumberChannels);
00898                 if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
00899                     KdPrint2((PRINT_PREFIX "MemIo\n"));
00900                     MemIo = TRUE;
00901                 }
00902                 deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
00903                 deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
00904             }
00905             if(/*deviceExtension->*/BaseMemAddress) {
00906                 KdPrint2((PRINT_PREFIX "UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress));
00907                 if(ChipFlags & VIABAR) {
00908 
00909                     ULONG BaseIoAddressBM_0;
00910                     ULONG BaseIo;
00911 
00912                     KdPrint2((PRINT_PREFIX "UniataChipDetect: VIABAR\n"));
00913                     /*deviceExtension->*/BaseIoAddressBM_0 = /*(PIDE_BUSMASTER_REGISTERS)*/
00914                         AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, 4, 0,
00915                                         sizeof(IDE_BUSMASTER_REGISTERS)*deviceExtension->NumberChannels);
00916                     deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
00917                     for(c=0; c<deviceExtension->NumberChannels; c++) {
00918 
00919                         chan = &deviceExtension->chan[c];
00920 
00921                         BaseIo = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, c, 0, /*0x80*/ sizeof(IDE_REGISTERS_1) + sizeof(IDE_REGISTERS_2)*2);
00922 
00923                         for (i=0; i<=IDX_IO1_SZ; i++) {
00924                             chan->RegTranslation[IDX_IO1+i].Addr           = BaseIo + i;
00925                         }
00926                         chan->RegTranslation[IDX_IO2_AltStatus].Addr       = BaseIo + sizeof(IDE_REGISTERS_1) + 2;
00927                         UniataInitSyncBaseIO(chan);
00928 
00929                         for (i=0; i<=IDX_BM_IO_SZ; i++) {
00930                             chan->RegTranslation[IDX_BM_IO+i].Addr         = BaseIoAddressBM_0 + sizeof(IDE_BUSMASTER_REGISTERS)*c + i;
00931                         }
00932 
00933                     }
00934                 }
00935                 for(c=0; c<deviceExtension->NumberChannels; c++) {
00936                     chan = &deviceExtension->chan[c];
00937                     if((ChipFlags & VIABAR) && (c==2)) {
00938                         // Do not setup SATA registers for PATA part
00939                         for (i=0; i<=IDX_SATA_IO_SZ; i++) {
00940                             chan->RegTranslation[IDX_SATA_IO+i].Addr = 0;
00941                             chan->RegTranslation[IDX_SATA_IO+i].MemIo = 0;
00942                         }
00943                         break;
00944                     }
00945                     chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + (c * IoSize);
00946                     chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
00947                     chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + 4 + (c * IoSize);
00948                     chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
00949                     chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + 8 + (c * IoSize);
00950                     chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
00951 
00952                     chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
00953                 }
00954 
00955             }
00956         }
00957         break; }
00958     case ATA_INTEL_ID: {
00959 
00960         BOOLEAN IsPata;
00961         if(!(ChipFlags & UNIATA_SATA)) {
00962             break;
00963         }
00964 
00965         /* the intel 31244 needs special care if in DPA mode */
00966         if(DeviceID == 3200 && // Intel 31244
00967            pciData->SubClass != PCI_DEV_SUBCLASS_IDE) {
00968 
00969             KdPrint2((PRINT_PREFIX "UniataChipDetect: Intel 31244, DPA mode\n"));
00970             BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
00971                                     0, 0, 0x0c00);
00972             if((*ConfigInfo->AccessRanges)[0].RangeInMemory) {
00973                 KdPrint2((PRINT_PREFIX "MemIo\n"));
00974                 MemIo = TRUE;
00975             }
00976             deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
00977             deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
00978             deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
00979 
00980             for(c=0; c<deviceExtension->NumberChannels; c++) {
00981                 ULONG offs = 0x200 + c*0x200;
00982 
00983                 chan = &deviceExtension->chan[c];
00984                 for (i=0; i<=IDX_IO1_SZ; i++) {
00985                     chan->RegTranslation[IDX_IO1+i].MemIo          = MemIo;
00986                     chan->RegTranslation[IDX_IO1_o+i].MemIo        = MemIo;
00987                 }
00988 
00989                 chan->RegTranslation[IDX_IO1_i_Data        ].Addr       = BaseMemAddress + 0x00 + offs;
00990                 chan->RegTranslation[IDX_IO1_i_Error       ].Addr       = BaseMemAddress + 0x04 + offs;
00991                 chan->RegTranslation[IDX_IO1_i_BlockCount  ].Addr       = BaseMemAddress + 0x08 + offs;
00992                 chan->RegTranslation[IDX_IO1_i_BlockNumber ].Addr       = BaseMemAddress + 0x0c + offs;
00993                 chan->RegTranslation[IDX_IO1_i_CylinderLow ].Addr       = BaseMemAddress + 0x10 + offs;
00994                 chan->RegTranslation[IDX_IO1_i_CylinderHigh].Addr       = BaseMemAddress + 0x14 + offs;
00995                 chan->RegTranslation[IDX_IO1_i_DriveSelect ].Addr       = BaseMemAddress + 0x18 + offs;
00996                 chan->RegTranslation[IDX_IO1_i_Status      ].Addr       = BaseMemAddress + 0x1c + offs;
00997 
00998                 UniataInitSyncBaseIO(chan);
00999 
01000                 chan->RegTranslation[IDX_IO1_o_Command     ].Addr       = BaseMemAddress + 0x1d + offs;
01001                 chan->RegTranslation[IDX_IO1_o_Feature     ].Addr       = BaseMemAddress + 0x06 + offs;
01002                 chan->RegTranslation[IDX_IO2_o_Control     ].Addr       = BaseMemAddress + 0x29 + offs;
01003 
01004                 chan->RegTranslation[IDX_IO2_AltStatus].Addr       = BaseMemAddress + 0x28 + offs;
01005                 chan->RegTranslation[IDX_IO2_AltStatus].MemIo      = MemIo;
01006 
01007                 chan->RegTranslation[IDX_BM_Command].Addr          = BaseMemAddress + offs + 0x70;
01008                 chan->RegTranslation[IDX_BM_Command].MemIo         = MemIo;
01009                 chan->RegTranslation[IDX_BM_Status].Addr           = BaseMemAddress + offs + 0x72;
01010                 chan->RegTranslation[IDX_BM_Status].MemIo          = MemIo;
01011                 chan->RegTranslation[IDX_BM_PRD_Table].Addr        = BaseMemAddress + offs + 0x74;
01012                 chan->RegTranslation[IDX_BM_PRD_Table].MemIo       = MemIo;
01013 
01014                 chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + 0x100 + offs;
01015                 chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
01016                 chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + 0x104 + offs;
01017                 chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
01018                 chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + 0x108 + offs;
01019                 chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
01020 
01021                 chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
01022             }
01023 
01024             break;
01025         }
01026         if(deviceExtension->MaxTransferMode >= ATA_SA150) {
01027             GetPciConfig1(0x90, tmp8);
01028             KdPrint2((PRINT_PREFIX "Intel chip config: %x\n", tmp8));
01029             /* SATA parts can be either compat or AHCI */
01030             if(ChipFlags & UNIATA_AHCI) {
01031 
01032                 if(tmp8 & 0xc0) {
01033                     //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n"));
01034                     //return FALSE;
01035                     KdPrint2((PRINT_PREFIX "try run AHCI\n"));
01036                     break;
01037                 }
01038                 KdPrint2((PRINT_PREFIX "Compatible mode\n"));
01039             }
01040             deviceExtension->HwFlags &= ~UNIATA_AHCI;
01041 
01042             /* if BAR(5) is IO it should point to SATA interface registers */
01043             BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
01044                                     5, 0, 0x10);
01045             if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
01046                 KdPrint2((PRINT_PREFIX "MemIo\n"));
01047                 MemIo = TRUE;
01048             }
01049             deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
01050             deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
01051 
01052             for(c=0; c<deviceExtension->NumberChannels; c++) {
01053                 chan = &deviceExtension->chan[c];
01054                 IsPata = FALSE;
01055                 if(ChipFlags & ICH5) {
01056                     KdPrint2((PRINT_PREFIX "ICH5\n"));
01057                     if ((tmp8 & 0x04) == 0) {
01058                         chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
01059                     } else if ((tmp8 & 0x02) == 0) {
01060                         if(c != 0) {
01061                             IsPata = TRUE;
01062                             //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
01063                         }
01064                     } else if ((tmp8 & 0x02) != 0) {
01065                         if(c != 1) {
01066                             IsPata = TRUE;
01067                             //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
01068                         }
01069                     }
01070                 } else
01071                 if(ChipFlags & I6CH2) {
01072                     KdPrint2((PRINT_PREFIX "I6CH2\n"));
01073                     chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
01074                 } else {
01075                     KdPrint2((PRINT_PREFIX "other Intel\n"));
01076                     switch(tmp8 & 0x03) {
01077                     case 2:
01078                         if(c!=0) {
01079                             // PATA
01080                             IsPata = TRUE;
01081                         }
01082                         break;
01083                     case 1:
01084                         if(c!=1) {
01085                             // PATA
01086                             IsPata = TRUE;
01087                         }
01088                         break;
01089                     }
01090                 }
01091 
01092                 if(IsPata) {
01093                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
01094                     KdPrint2((PRINT_PREFIX "PATA part\n"));
01095                 } else {
01096 
01097                     if(/*(ChipFlags & ICH5) &&*/ BaseMemAddress) {
01098                         KdPrint2((PRINT_PREFIX "BaseMemAddress[5] -> indexed\n"));
01099                         chan->RegTranslation[IDX_INDEXED_ADDR].Addr        = BaseMemAddress + 0;
01100                         chan->RegTranslation[IDX_INDEXED_ADDR].MemIo       = MemIo;
01101                         chan->RegTranslation[IDX_INDEXED_DATA].Addr        = BaseMemAddress + 4;
01102                         chan->RegTranslation[IDX_INDEXED_DATA].MemIo       = MemIo;
01103                     }
01104                     if((ChipFlags & ICH5) || BaseMemAddress) {
01105 
01106                         KdPrint2((PRINT_PREFIX "io indexed\n"));
01107                         // Rather interesting way of register access...
01108                         ChipType = INTEL_IDX;
01109                         deviceExtension->HwFlags &= ~CHIPTYPE_MASK;
01110                         deviceExtension->HwFlags |= ChipType;
01111 
01112                         chan->RegTranslation[IDX_SATA_SStatus].Addr        = 0x200*c + 0;
01113                         chan->RegTranslation[IDX_SATA_SStatus].Proc        = 1;
01114                         chan->RegTranslation[IDX_SATA_SError].Addr         = 0x200*c + 2;
01115                         chan->RegTranslation[IDX_SATA_SError].Proc         = 1;
01116                         chan->RegTranslation[IDX_SATA_SControl].Addr       = 0x200*c + 1;
01117                         chan->RegTranslation[IDX_SATA_SControl].Proc       = 1;
01118                     }
01119                 }
01120 
01121             } // end for()
01122 
01123             // rest of INIT staff is in AtapiChipInit()
01124 
01125         } // ATA_SA150
01126         break; }
01127     case ATA_CYRIX_ID:
01128         /* Cyrix 5530 ATA33 controller */
01129         if(deviceExtension->DevID == 0x01021078) { 
01130             ConfigInfo->AlignmentMask = 0x0f;
01131             deviceExtension->MaximumDmaTransferLength = 63*1024;
01132         }
01133         break;
01134     case ATA_JMICRON_ID:
01135         /* New JMicron PATA controllers */
01136         GetPciConfig1(0xdf, tmp8);
01137         if(tmp8 & 0x40) {
01138             KdPrint(("  Check JMicron AHCI\n"));
01139             if(Ata_is_ahci_dev(pciData)) {
01140                 ChipFlags |= UNIATA_AHCI;
01141                 deviceExtension->HwFlags |= UNIATA_AHCI;
01142             } else {
01143                 KdPrint(("  JMicron PATA\n"));
01144             }
01145         } else {
01146             /* set controller configuration to a combined setup we support */
01147             SetPciConfig4(0x40, 0x80c0a131);
01148             SetPciConfig4(0x80, 0x01200000);
01149             //KdPrint(("  JMicron Combined (not supported yet)\n"));
01150             //return STATUS_NOT_FOUND;
01151         }
01152         break;
01153     }
01154 
01155     return STATUS_SUCCESS;
01156 
01157 } // end UniataChipDetect()
01158 
01159 
01160 /*
01161     Do some 'magic staff' for VIA SouthBridge
01162     This will prevent data losses
01163 */
01164 VOID
01165 NTAPI
01166 AtapiViaSouthBridgeFixup(
01167     IN PVOID  HwDeviceExtension,
01168     IN BUS_DATA_TYPE  BusDataType,
01169     IN ULONG  SystemIoBusNumber,
01170     IN ULONG  slotNumber
01171     )
01172 {
01173     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
01174     PCI_COMMON_CONFIG     pciData;
01175     ULONG                 funcNumber;
01176     ULONG                 busDataRead;
01177 
01178     ULONG   VendorID;
01179     ULONG   DeviceID;
01180     PCI_SLOT_NUMBER       slotData;
01181     ULONG dev_id;
01182     BOOLEAN found = FALSE;
01183 
01184     slotData.u.AsULONG = slotNumber;
01185     for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
01186 
01187         slotData.u.bits.FunctionNumber = funcNumber;
01188 
01189         busDataRead = ScsiPortGetBusData(HwDeviceExtension,
01190                                          PCIConfiguration,
01191                                          SystemIoBusNumber,
01192                                          slotData.u.AsULONG,
01193                                          &pciData,
01194                                          PCI_COMMON_HDR_LENGTH);
01195 
01196         if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
01197             continue;
01198         }
01199 
01200         VendorID  = pciData.VendorID;
01201         DeviceID  = pciData.DeviceID;
01202         dev_id = (VendorID | (DeviceID << 16));
01203 
01204         if (dev_id == 0x03051106 ||         /* VIA VT8363 */
01205             dev_id == 0x03911106 ||         /* VIA VT8371 */
01206             dev_id == 0x31021106 ||         /* VIA VT8662 */
01207             dev_id == 0x31121106) {         /* VIA VT8361 */
01208             UCHAR reg76;
01209 
01210             GetPciConfig1(0x76, reg76);
01211 
01212             if ((reg76 & 0xf0) != 0xd0) {
01213                 SetPciConfig1(0x75, 0x80);
01214                 SetPciConfig1(0x76, (reg76 & 0x0f) | 0xd0);
01215             }
01216             found = TRUE;
01217             break;
01218         }
01219     }
01220     if(!found) {
01221         deviceExtension->HwFlags &= ~VIABUG;
01222     }
01223 } // end AtapiViaSouthBridgeFixup()
01224 
01225 /*
01226     Do some 'magic staff' for ROSB SouthBridge
01227     This will prevent data losses
01228 */
01229 VOID
01230 NTAPI
01231 AtapiRosbSouthBridgeFixup(
01232     IN PVOID  HwDeviceExtension,
01233     IN BUS_DATA_TYPE  BusDataType,
01234     IN ULONG  SystemIoBusNumber,
01235     IN ULONG  slotNumber
01236     )
01237 {
01238     //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
01239     PCI_COMMON_CONFIG     pciData;
01240     ULONG                 funcNumber;
01241     ULONG                 busDataRead;
01242 
01243     ULONG   VendorID;
01244     ULONG   DeviceID;
01245     PCI_SLOT_NUMBER       slotData;
01246     ULONG dev_id;
01247 //    BOOLEAN found = FALSE;
01248 
01249     /* locate the ISA part in the southbridge and enable UDMA33 */
01250     slotData.u.AsULONG = slotNumber;
01251     for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
01252 
01253         slotData.u.bits.FunctionNumber = funcNumber;
01254 
01255         busDataRead = ScsiPortGetBusData(HwDeviceExtension,
01256                                          PCIConfiguration,
01257                                          SystemIoBusNumber,
01258                                          slotData.u.AsULONG,
01259                                          &pciData,
01260                                          PCI_COMMON_HDR_LENGTH);
01261 
01262         if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
01263             continue;
01264         }
01265 
01266         VendorID  = pciData.VendorID;
01267         DeviceID  = pciData.DeviceID;
01268         dev_id = (VendorID | (DeviceID << 16));
01269 
01270         if (dev_id == ATA_ROSB4_ISA) {         /*  */
01271             ChangePciConfig4(0x64, ((a & ~0x00002000) | 0x00004000));
01272             break;
01273         }
01274     }
01275 } // end AtapiRosbSouthBridgeFixup()
01276 
01277 /*
01278     Do some 'magic staff' for ROSB SouthBridge
01279     This will prevent data losses
01280 */
01281 VOID
01282 NTAPI
01283 AtapiAliSouthBridgeFixup(
01284     IN PVOID  HwDeviceExtension,
01285     IN BUS_DATA_TYPE  BusDataType,
01286     IN ULONG  SystemIoBusNumber,
01287     IN ULONG  slotNumber,
01288     IN ULONG  c
01289     )
01290 {
01291     //PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
01292     PCI_COMMON_CONFIG     pciData;
01293     ULONG                 funcNumber;
01294     ULONG                 busDataRead;
01295 
01296     ULONG   VendorID;
01297     ULONG   DeviceID;
01298     PCI_SLOT_NUMBER       slotData;
01299     ULONG dev_id;
01300 //    BOOLEAN found = FALSE;
01301 
01302     /* workaround for datacorruption bug found on at least SUN Blade-100
01303      * find the ISA function on the southbridge and disable then enable
01304      * the ATA channel tristate buffer */
01305     slotData.u.AsULONG = slotNumber;
01306     for(funcNumber = 0; funcNumber < PCI_MAX_FUNCTION; funcNumber++) {
01307 
01308         slotData.u.bits.FunctionNumber = funcNumber;
01309 
01310         busDataRead = ScsiPortGetBusData(HwDeviceExtension,
01311                                          PCIConfiguration,
01312                                          SystemIoBusNumber,
01313                                          slotData.u.AsULONG,
01314                                          &pciData,
01315                                          PCI_COMMON_HDR_LENGTH);
01316 
01317         if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
01318             continue;
01319         }
01320 
01321         VendorID  = pciData.VendorID;
01322         DeviceID  = pciData.DeviceID;
01323         dev_id = (VendorID | (DeviceID << 16));
01324 
01325         if (dev_id == ATA_ALI_1533) {         /* SOUTH */
01326             ChangePciConfig1(0x58, (a & ~(0x04 << c)));
01327             ChangePciConfig1(0x58, (a |  (0x04 << c)));
01328             break;
01329         }
01330     }
01331 } // end AtapiRosbSouthBridgeFixup()
01332 
01333 ULONG
01334 NTAPI
01335 hpt_cable80(
01336     IN PHW_DEVICE_EXTENSION deviceExtension,
01337     IN ULONG channel               // physical channel number (0-1)
01338     )
01339 {
01340     PVOID HwDeviceExtension = (PVOID)deviceExtension;
01341     ULONG slotNumber = deviceExtension->slotNumber;
01342     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
01343 
01344     ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
01345 
01346     UCHAR reg, val, res;
01347     PCI_SLOT_NUMBER slotData;
01348 
01349     slotData.u.AsULONG = deviceExtension->slotNumber;
01350 
01351     if(ChipType == HPT374 && slotData.u.bits.FunctionNumber == 1)  {
01352         reg = channel ? 0x57 : 0x53;
01353         GetPciConfig1(reg, val);
01354         SetPciConfig1(reg, val | 0x80);
01355     }
01356     else {
01357         reg = 0x5b;
01358         GetPciConfig1(reg, val);
01359         SetPciConfig1(reg, val & 0xfe);
01360     }
01361     GetPciConfig1(0x5a, res);
01362     res = res & (channel ? 0x01 : 0x02);
01363     SetPciConfig1(reg, val);
01364     return !res;
01365 } // end hpt_cable80()
01366 
01367 
01368 ULONG
01369 NTAPI
01370 via_cable80(
01371     IN PHW_DEVICE_EXTENSION deviceExtension,
01372     IN ULONG channel               // physical channel number (0-1)
01373     )
01374 {
01375     PVOID HwDeviceExtension = (PVOID)deviceExtension;
01376     ULONG slotNumber = deviceExtension->slotNumber;
01377     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
01378 
01379     ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
01380 
01381     ULONG reg50;
01382     ULONG a;
01383     ULONG i, j;
01384     BOOLEAN res;
01385 
01386     GetPciConfig1(0x50, reg50);
01387 
01388     switch(ChipType) {
01389     case VIA133:
01390         a = 8;
01391         break;
01392     case VIA100:
01393         a = 4;
01394         break;
01395     case VIA66:
01396         a = 2;
01397         break;
01398     default:
01399         return false;
01400     }
01401 
01402     res = FALSE;
01403     for (j=0; j>=2; i -= 8) {
01404         i = (3-(channel*2+j))*8;
01405         if (((reg50 >> (i & 0x10)) & 8) &&
01406             ((reg50 >> i) & 0x20) &&
01407              (((reg50 >> i) & 7) < a)) {
01408 
01409             res |= TRUE; //(1 << (1 - (i >> 4)));
01410         }
01411     }
01412     return res;
01413 
01414 } // end via_cable80()
01415 
01416 BOOLEAN
01417 NTAPI
01418 generic_cable80(
01419     IN PHW_DEVICE_EXTENSION deviceExtension,
01420     IN ULONG channel,               // physical channel number (0-1)
01421     IN ULONG pci_reg,
01422     IN ULONG bit_offs
01423     )
01424 {
01425     PVOID HwDeviceExtension = (PVOID)deviceExtension;
01426     ULONG slotNumber = deviceExtension->slotNumber;
01427     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
01428 
01429     //ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
01430     PHW_CHANNEL chan;
01431     ULONG  c; // logical channel (for Compatible Mode controllers)
01432     UCHAR tmp8;
01433 
01434     c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
01435     chan = &deviceExtension->chan[c];
01436 
01437     GetPciConfig1(pci_reg, tmp8);
01438     if(!(tmp8 & (1 << (channel << bit_offs)))) {
01439         chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01440         return FALSE;
01441     }
01442 
01443     return TRUE;
01444 } // end generic_cable80()
01445 
01446 VOID
01447 NTAPI
01448 UniAtaReadLunConfig(
01449     IN PHW_DEVICE_EXTENSION deviceExtension,
01450     IN ULONG channel,  // physical channel
01451     IN ULONG DeviceNumber
01452     )
01453 {
01454     ULONG tmp32;
01455     PHW_CHANNEL chan;
01456     PHW_LU_EXTENSION   LunExt;
01457     ULONG c;
01458 
01459     c = channel - deviceExtension->Channel; // logical channel
01460 
01461     chan = &deviceExtension->chan[c];
01462     DeviceNumber = (DeviceNumber % deviceExtension->NumberLuns);
01463     LunExt = chan->lun[DeviceNumber];
01464 
01465     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadCacheEnable", 1);
01466     LunExt->opt_ReadCacheEnable = tmp32 ? TRUE : FALSE;
01467 
01468     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"WriteCacheEnable", 1);
01469     LunExt->opt_WriteCacheEnable = tmp32 ? TRUE : FALSE;
01470 
01471     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"MaxTransferMode", chan->MaxTransferMode);
01472     LunExt->opt_MaxTransferMode = tmp32;
01473 
01474     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"PreferedTransferMode", 0xffffffff);
01475     LunExt->opt_PreferedTransferMode = tmp32;
01476 
01477     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadOnly", 0);
01478     if(tmp32 <= 2) {
01479         LunExt->opt_ReadOnly = (UCHAR)tmp32;
01480     }
01481 
01482     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"GeomType", 0xffffffff);
01483     if(tmp32 > 2) {
01484         tmp32 = 0xffffffff;
01485     }
01486     LunExt->opt_GeomType = tmp32;
01487 
01488     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"Hidden", 0);
01489     if(tmp32) {
01490         LunExt->DeviceFlags |= DFLAGS_HIDDEN;
01491     }
01492 
01493     return;
01494 } // end UniAtaReadLunConfig()
01495 
01496 BOOLEAN
01497 NTAPI
01498 AtapiReadChipConfig(
01499     IN PVOID HwDeviceExtension,
01500     IN ULONG DeviceNumber,
01501     IN ULONG channel // physical channel
01502     )
01503 {
01504     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
01505     PHW_CHANNEL chan;
01506     ULONG  tmp32;
01507     ULONG  c; // logical channel (for Compatible Mode controllers)
01508     ULONG  i;
01509 
01510     KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: devExt %#x\n", deviceExtension ));
01511     ASSERT(deviceExtension);
01512 
01513     if(channel != CHAN_NOT_SPECIFIED) {
01514         c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
01515     } else {
01516         c = CHAN_NOT_SPECIFIED;
01517     }
01518 
01519     KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: dev %#x, ph chan %d\n", DeviceNumber, channel ));
01520 
01521     if(channel == CHAN_NOT_SPECIFIED) {
01522         if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", FALSE)) {
01523             deviceExtension->simplexOnly = TRUE;
01524         }
01525         deviceExtension->opt_AtapiDmaZeroTransfer = FALSE;
01526         deviceExtension->opt_AtapiDmaControlCmd   = FALSE;
01527         deviceExtension->opt_AtapiDmaRawRead      = g_opt_AtapiDmaRawRead; 
01528         deviceExtension->opt_AtapiDmaReadWrite    = TRUE;
01529     }
01530 
01531     if(c == CHAN_NOT_SPECIFIED) {
01532         KdPrint2((PRINT_PREFIX "MaxTransferMode (base): %#x\n", deviceExtension->MaxTransferMode));
01533         for(c=0; c<deviceExtension->NumberChannels; c++) {
01534             chan = &deviceExtension->chan[c];
01535             chan->MaxTransferMode = deviceExtension->MaxTransferMode;
01536             tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", chan->MaxTransferMode);
01537             if(tmp32 != 0xffffffff) {
01538                 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
01539                 chan->MaxTransferMode = tmp32;
01540             }
01541             //UniAtaReadLunConfig(deviceExtension, c, 0);
01542             //UniAtaReadLunConfig(deviceExtension, c, 1);
01543         }
01544 
01545         deviceExtension->opt_AtapiDmaZeroTransfer =
01546             AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaZeroTransfer", deviceExtension->opt_AtapiDmaZeroTransfer) ?
01547                TRUE : FALSE;
01548 
01549         deviceExtension->opt_AtapiDmaControlCmd =
01550             AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaControlCmd", deviceExtension->opt_AtapiDmaControlCmd) ?
01551                TRUE : FALSE;
01552 
01553         deviceExtension->opt_AtapiDmaRawRead =
01554             AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead", deviceExtension->opt_AtapiDmaRawRead) ?
01555                TRUE : FALSE;
01556 
01557         deviceExtension->opt_AtapiDmaReadWrite =
01558             AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaReadWrite", deviceExtension->opt_AtapiDmaReadWrite) ?
01559                TRUE : FALSE;
01560 
01561     } else {
01562         chan = &deviceExtension->chan[c];
01563         chan->MaxTransferMode = deviceExtension->MaxTransferMode;
01564         tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"MaxTransferMode", chan->MaxTransferMode);
01565         if(tmp32 != 0xffffffff) {
01566             KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
01567             chan->MaxTransferMode = tmp32;
01568         }
01569         tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"ReorderEnable", TRUE);
01570         chan->UseReorder = tmp32 ? TRUE : FALSE;
01571 
01572         for(i=0; i<deviceExtension->NumberLuns; i++) {
01573             UniAtaReadLunConfig(deviceExtension, channel, i);
01574         }
01575     }
01576 
01577     return TRUE;
01578 } // end AtapiReadChipConfig()
01579 
01580 BOOLEAN
01581 NTAPI
01582 AtapiChipInit(
01583     IN PVOID HwDeviceExtension,
01584     IN ULONG DeviceNumber,
01585     IN ULONG channel // physical channel
01586     )
01587 {
01588     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
01589     ULONG slotNumber = deviceExtension->slotNumber;
01590     ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
01591     ULONG VendorID =  deviceExtension->DevID        & 0xffff;
01592 #ifdef _DEBUG
01593     ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
01594 #endif
01595     ULONG RevID    =  deviceExtension->RevID;
01596 //    ULONG i;
01597 //    BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo;
01598     ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
01599     ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
01600     PHW_CHANNEL chan;
01601     UCHAR  tmp8;
01602     USHORT tmp16;
01603     ULONG  tmp32;
01604     ULONG  c; // logical channel (for Compatible Mode controllers)
01605     BOOLEAN CheckCable = FALSE;
01606     //ULONG BaseIoAddress;
01607 
01608     switch(channel) {
01609     case CHAN_NOT_SPECIFIED_CHECK_CABLE:
01610         CheckCable = TRUE;
01611         /* FALLTHROUGH */
01612     case CHAN_NOT_SPECIFIED:
01613         c = CHAN_NOT_SPECIFIED;
01614         break;
01615     default:
01616         c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
01617     }
01618 
01619     KdPrint2((PRINT_PREFIX "AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber, channel ));
01620 
01621     KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags));
01622     KdPrint2((PRINT_PREFIX "VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID, DeviceID, RevID));
01623 
01624     if(deviceExtension->UnknownDev) {
01625         KdPrint2((PRINT_PREFIX "  Unknown chip\n" ));
01626         //return TRUE;
01627         VendorID = 0xffffffff;
01628     }
01629 
01630 
01631     if(ChipFlags & UNIATA_AHCI) {
01632         /* if BAR(5) is IO it should point to SATA interface registers */
01633         if(!deviceExtension->BaseIoAHCI_0.Addr) {
01634             KdPrint2((PRINT_PREFIX "  !BaseIoAHCI_0, exiting\n" ));
01635             return FALSE;
01636         }
01637         if(c == CHAN_NOT_SPECIFIED) {
01638             return UniataAhciInit(HwDeviceExtension);
01639         } else
01640         if(c<deviceExtension->NumberChannels) {
01641             KdPrint2((PRINT_PREFIX "  AHCI single channel init\n" ));
01642             UniataAhciReset(HwDeviceExtension, c);
01643             return TRUE;
01644         } else {
01645             KdPrint2((PRINT_PREFIX "  AHCI non-existent channel\n" ));
01646             return FALSE;
01647         }
01648     }
01649 
01650     switch(VendorID) {
01651 //  case ATA_ACARD_ID:
01652 //      break;
01653     case ATA_ACER_LABS_ID:
01654         if(ChipFlags & UNIATA_SATA) {
01655             if(c == CHAN_NOT_SPECIFIED) {
01656                 for(c=0; c<deviceExtension->NumberChannels; c++) {
01657                     chan = &deviceExtension->chan[c];
01658                     chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
01659                     /* the southbridge might need the data corruption fix */
01660                     if(RevID == 0xc2 || RevID == 0xc3) {
01661                         AtapiAliSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
01662                                                  SystemIoBusNumber, slotNumber, c);
01663                     }
01664                 }
01665                 /* enable PCI interrupt */
01666                 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
01667             }
01668         } else
01669         if(ChipFlags & ALINEW) {
01670             if(c == CHAN_NOT_SPECIFIED) {
01671                 /* use device interrupt as byte count end */
01672                 ChangePciConfig1(0x4a, (a | 0x20));
01673                 /* enable cable detection and UDMA support on newer chips, rev < 0xc7 */
01674                 if(RevID < 0xc7) {
01675                     ChangePciConfig1(0x4b, (a | 0x09));
01676                 }
01677 
01678                 /* enable ATAPI UDMA mode */
01679                 ChangePciConfig1(0x53, (a | (RevID >= 0xc7 ? 0x03 : 0x01)));
01680 
01681             } else {
01682                 // check 80-pin cable
01683                 generic_cable80(deviceExtension, channel, 0x4a, 0);
01684             }
01685         } else {
01686             if(c == CHAN_NOT_SPECIFIED) {
01687                 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
01688                 ChangePciConfig1(0x53, (a | 0x03));
01689             } else {
01690                 // ATAPI DMA R/O
01691                 deviceExtension->chan[c].ChannelCtrlFlags |= CTRFLAGS_DMA_RO;
01692             }
01693         }
01694         break;
01695     case ATA_AMD_ID:
01696         if(c == CHAN_NOT_SPECIFIED) {
01697             /* set prefetch, postwrite */
01698             if(ChipFlags & AMDBUG) {
01699                 ChangePciConfig1(0x41, (a & 0x0f));
01700             } else {
01701                 ChangePciConfig1(0x41, (a | 0xf0));
01702             }
01703         }
01704         if(deviceExtension->MaxTransferMode < ATA_UDMA2)
01705             break;
01706         // check 80-pin cable
01707         if(!(ChipFlags & UNIATA_NO80CHK)) {
01708             if(c == CHAN_NOT_SPECIFIED) {
01709                 // do nothing
01710             } else {
01711                 generic_cable80(deviceExtension, channel, 0x42, 0);
01712             }
01713         }
01714         break;
01715     case ATA_HIGHPOINT_ID:
01716 
01717         if(c == CHAN_NOT_SPECIFIED) {
01718 
01719             if(ChipFlags & HPTOLD) {
01720                 /* turn off interrupt prediction */
01721                 ChangePciConfig1(0x51, (a & ~0x80));
01722             } else {
01723                 /* turn off interrupt prediction */
01724                 ChangePciConfig1(0x51, (a & ~0x03));
01725                 ChangePciConfig1(0x55, (a & ~0x03));
01726                 /* turn on interrupts */
01727                 ChangePciConfig1(0x5a, (a & ~0x10));
01728                 /* set clocks etc */
01729                 if(ChipType < HPT372) {
01730                     SetPciConfig1(0x5b, 0x22);
01731                 } else {
01732                     ChangePciConfig1(0x5b, ((a & 0x01) | 0x20));
01733                 }
01734             }
01735 
01736         } else {
01737             // check 80-pin cable
01738             chan = &deviceExtension->chan[c];
01739             if(!hpt_cable80(deviceExtension, channel)) {
01740                 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01741             }
01742         }
01743         break;
01744     case ATA_INTEL_ID: {
01745         BOOLEAN IsPata;
01746         USHORT reg54;
01747         UCHAR tmp8;
01748         if(ChipFlags & UNIATA_SATA) {
01749 
01750             KdPrint2((PRINT_PREFIX "Intel SATA\n"));
01751             if(ChipFlags & UNIATA_AHCI) {
01752                 KdPrint2((PRINT_PREFIX "Do nothing for AHCI\n"));
01753                 break;
01754             }
01755             if(c == CHAN_NOT_SPECIFIED) {
01756                 KdPrint2((PRINT_PREFIX "Base init\n"));
01757                 /* force all ports active "the legacy way" */
01758                 ChangePciConfig2(0x92, (a | 0x0f));
01759                 /* enable PCI interrupt */
01760                 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
01761 
01762             } else {
01763 
01764                 KdPrint2((PRINT_PREFIX "channel init\n"));
01765 
01766                 GetPciConfig1(0x90, tmp8);
01767                 KdPrint2((PRINT_PREFIX "reg 90: %x, init lun map\n", tmp8));
01768 
01769                 KdPrint2((PRINT_PREFIX "chan %d\n", c));
01770                 chan = &deviceExtension->chan[c];
01771                 IsPata = FALSE;
01772                 if(ChipFlags & ICH5) {
01773                     KdPrint2((PRINT_PREFIX "ICH5\n"));
01774                     if ((tmp8 & 0x04) == 0) {
01775                         chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
01776                         chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ^ c;
01777                         chan->lun[1]->SATA_lun_map = 0;
01778                     } else if ((tmp8 & 0x02) == 0) {
01779                         if(c == 0) {
01780                             chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
01781                             chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
01782                         } else {
01783                             IsPata = TRUE;
01784                             //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
01785                         }
01786                     } else if ((tmp8 & 0x02) != 0) {
01787                         if(c == 1) {
01788                             chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
01789                             chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
01790                         } else {
01791                             IsPata = TRUE;
01792                             //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
01793                         }
01794                     }
01795                 } else
01796                 if(ChipFlags & I6CH2) {
01797                     KdPrint2((PRINT_PREFIX "I6CH2\n"));
01798                     chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
01799                     chan->lun[0]->SATA_lun_map = c ? 4 : 5;
01800                     chan->lun[1]->SATA_lun_map = 0;
01801                 } else {
01802                     KdPrint2((PRINT_PREFIX "other Intel\n"));
01803                     switch(tmp8 & 0x03) {
01804                     case 0:
01805                         chan->lun[0]->SATA_lun_map = 0+c;
01806                         chan->lun[1]->SATA_lun_map = 2+c;
01807                         break;
01808                     case 2:
01809                         if(c==0) {
01810                             chan->lun[0]->SATA_lun_map = 0;
01811                             chan->lun[1]->SATA_lun_map = 2;
01812                         } else {
01813                             // PATA
01814                             IsPata = TRUE;
01815                         }
01816                         break;
01817                     case 1:
01818                         if(c==1) {
01819                             chan->lun[0]->SATA_lun_map = 1;
01820                             chan->lun[1]->SATA_lun_map = 3;
01821                         } else {
01822                             // PATA
01823                             IsPata = TRUE;
01824                         }
01825                         break;
01826                     }
01827                 }
01828 
01829                 if(IsPata) {
01830                     KdPrint2((PRINT_PREFIX "PATA part\n"));
01831                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
01832                 }
01833 
01834                 if(ChipType == INTEL_IDX) {
01835                     KdPrint2((PRINT_PREFIX "io indexed\n"));
01836                     //for(c=0; c<deviceExtension->NumberChannels; c++) {
01837                         chan = &deviceExtension->chan[c];
01838                         UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
01839                         if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
01840                             UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 1);
01841                         }
01842                     //}
01843                 }
01844             }
01845 
01846             break;
01847         }
01848         if(deviceExtension->MaxTransferMode < ATA_UDMA2)
01849             break;
01850         // check 80-pin cable
01851         if(c == CHAN_NOT_SPECIFIED) {
01852             // do nothing
01853         } else {
01854             chan = &deviceExtension->chan[c];
01855             GetPciConfig2(0x54, reg54);
01856             if( ((reg54 >> (channel*2)) & 30) != 30) {
01857                 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01858             }
01859         }
01860         break; }
01861     case ATA_NVIDIA_ID: {
01862         if(ChipFlags & UNIATA_SATA) {
01863             if(c == CHAN_NOT_SPECIFIED) {
01864                 ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
01865                 /* enable control access */
01866                 ChangePciConfig1(0x50, (a | 0x04));
01867                 /* MCP55 seems to need some time to allow r_res2 read. */
01868                 AtapiStallExecution(10);
01869                 KdPrint2((PRINT_PREFIX "BaseIoAddressSATA_0=%x\n", deviceExtension->BaseIoAddressSATA_0.Addr));
01870                 if(ChipFlags & NVQ) {
01871                     /* clear interrupt status */
01872                     AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0x00ff00ff);
01873                     /* enable device and PHY state change interrupts */
01874                     AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 0x000d000d);
01875                     /* disable NCQ support */
01876                     AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400, 
01877                         AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400) & 0xfffffff9);
01878                 } else {
01879                     /* clear interrupt status */
01880                     AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0xff);
01881                     /* enable device and PHY state change interrupts */
01882                     AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 0xdd);
01883                 }
01884                 /* enable PCI interrupt */
01885                 ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
01886             } else {
01887                 //UniataSataPhyEnable(HwDeviceExtension, c);
01888             }
01889         } else {
01890             //UCHAR reg52;
01891             
01892             if(c == CHAN_NOT_SPECIFIED) {
01893                 /* set prefetch, postwrite */
01894                 ChangePciConfig1(0x51, (a & 0x0f));
01895             } else {
01896                 // check 80-pin cable
01897                 generic_cable80(deviceExtension, channel, 0x52, 1);
01898 /*                chan = &deviceExtension->chan[c];
01899                 GetPciConfig1(0x52, reg52);
01900                 if( !((reg52 >> (channel*2)) & 0x01)) {
01901                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01902                 }*/
01903             }
01904         }
01905         break; }
01906     case ATA_PROMISE_ID: {
01907         USHORT Reg50;
01908         switch(ChipType) {
01909         case PRNEW:
01910             /* setup clocks */
01911             if(c == CHAN_NOT_SPECIFIED) {
01912 //            ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
01913                 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11, 
01914                     AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) | 0x0a );
01915             }
01916             /* FALLTHROUGH */
01917         case PROLD:
01918             /* enable burst mode */
01919 //            ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
01920             if(c == CHAN_NOT_SPECIFIED) {
01921                 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1f, 
01922                     AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1f) | 0x01 );
01923             } else {
01924                 // check 80-pin cable
01925                 chan = &deviceExtension->chan[c];
01926                 GetPciConfig2(0x50, Reg50);
01927                 if(Reg50 & (1 << (channel+10))) {
01928                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01929                 }
01930             }
01931             break;
01932         case PRTX:
01933             if(c == CHAN_NOT_SPECIFIED) {
01934                 // do nothing
01935             } else {
01936                 // check 80-pin cable
01937                 chan = &deviceExtension->chan[c];
01938                 AtapiWritePort1(chan, IDX_BM_DeviceSpecific0, 0x0b);
01939                 if(AtapiReadPort1(chan, IDX_BM_DeviceSpecific1) & 0x04) {
01940                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01941                 }
01942             }
01943             break;
01944         case PRMIO:
01945             if(c == CHAN_NOT_SPECIFIED) {
01946                 if(ChipFlags & PRSATA) {
01947                     AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x6c, 0x000000ff);
01948                 }
01949             } else {
01950                 chan = &deviceExtension->chan[c];
01951                 AtapiWritePort4(chan, IDX_BM_Command, 
01952                     (AtapiReadPort4(chan, IDX_BM_Command) & ~0x00000f8f) | channel );
01953                 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
01954                 // check 80-pin cable
01955                 if(chan->MaxTransferMode < ATA_SA150 &&
01956                    (AtapiReadPort4(chan, IDX_BM_Command) & 0x01000000)) {
01957                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
01958                 }
01959             }
01960             break;
01961         }
01962         break; }
01963     case ATA_SERVERWORKS_ID:
01964         if(c == CHAN_NOT_SPECIFIED) {
01965             if(ChipType == SWKS33) {
01966                 AtapiRosbSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
01967                                          SystemIoBusNumber, slotNumber);
01968             } else {
01969                 ChangePciConfig1(0x5a, ((a & ~0x40) | ((ChipType == SWKS100) ? 0x03 : 0x02)));
01970             }
01971         }
01972         break;
01973     case ATA_ATI_ID:
01974         if(ChipType == SIIMIO) {
01975             KdPrint2((PRINT_PREFIX "ATI New\n"));
01976             // fall to SiI
01977         } else {
01978             KdPrint2((PRINT_PREFIX "ATI\n"));
01979             break;
01980         }
01981     case ATA_SILICON_IMAGE_ID:
01982   /*      if(ChipFlags & SIIENINTR) {
01983             SetPciConfig1(0x71, 0x01);
01984         }*/
01985         switch(ChipType) {
01986         case SIIMIO: {
01987 
01988             KdPrint2((PRINT_PREFIX "SII\n"));
01989             USHORT Reg79;
01990 
01991             if(c == CHAN_NOT_SPECIFIED) {
01992                 if(ChipFlags & SIISETCLK)  {
01993                     KdPrint2((PRINT_PREFIX "SIISETCLK\n"));
01994                     GetPciConfig1(0x8a, tmp8);
01995                     if ((tmp8 & 0x30) != 0x10)
01996                         ChangePciConfig1(0x8a, (a & 0xcf) | 0x10);
01997                     GetPciConfig1(0x8a, tmp8);
01998                     if ((tmp8 & 0x30) != 0x10) {
01999                         KdPrint2((PRINT_PREFIX "Sil 0680 could not set ATA133 clock\n"));
02000                         deviceExtension->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
02001                     }
02002                 }
02003             }
02004             if(deviceExtension->MaxTransferMode < ATA_SA150) {
02005                 // check 80-pin cable
02006                 if(c == CHAN_NOT_SPECIFIED) {
02007                     // do nothing
02008                 } else {
02009                     KdPrint2((PRINT_PREFIX "Check UDMA66 cable\n"));
02010                     chan = &deviceExtension->chan[c];
02011                     GetPciConfig2(0x79, Reg79);
02012                     if(Reg79 & (channel ? 0x02 : 0x01)) {
02013                         chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
02014                     }
02015                 }
02016             } else {
02017                 ULONG unit01 = (c & 1);
02018                 ULONG unit10 = (c & 2);
02019                 /* enable/disable PHY state change interrupt */
02020                 if(c == CHAN_NOT_SPECIFIED) {
02021                     for(c=0; c<deviceExtension->NumberChannels; c++) {
02022                         unit01 = (c & 1);
02023                         unit10 = (c & 2);
02024                         if(ChipFlags & SIINOSATAIRQ) {
02025                             KdPrint2((PRINT_PREFIX "Disable broken SATA intr on c=%x\n", c));
02026                             AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),0);
02027                         }
02028                     }
02029                 } else {
02030                     if(ChipFlags & SIINOSATAIRQ) {
02031                         KdPrint2((PRINT_PREFIX "Disable broken SATA intr on c=%x\n", c));
02032                         AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),0);
02033                     } else {
02034                         KdPrint2((PRINT_PREFIX "Enable SATA intr on c=%x\n", c));
02035                         AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16));
02036                     }
02037                 }
02038             }
02039             if(c == CHAN_NOT_SPECIFIED) {
02040                 /* enable interrupt as BIOS might not */
02041                 ChangePciConfig1(0x8a, (a & 0x3f));
02042                 // Enable 3rd and 4th channels
02043                 if (ChipFlags & SII4CH) {
02044                     KdPrint2((PRINT_PREFIX "SII4CH\n"));
02045                     AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0200, 0x00000002);
02046                 }
02047             } else {
02048                 chan = &deviceExtension->chan[c];
02049                 /* dont block interrupts */
02050                 //ChangePciConfig4(0x48, (a & ~0x03c00000));
02051                 tmp32 = AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48);
02052                 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48, (1 << 22) << c);
02053                 // flush
02054                 tmp32 = AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x48);
02055 
02056                 /* Initialize FIFO PCI bus arbitration */
02057                 GetPciConfig1(offsetof(PCI_COMMON_CONFIG, CacheLineSize), tmp8);
02058                 if(tmp8) {
02059                     KdPrint2((PRINT_PREFIX "SII: CacheLine=%d\n", tmp32));
02060                     tmp8 = (tmp8/8)+1;
02061                     AtapiWritePort2(chan, IDX_BM_DeviceSpecific1, ((USHORT)tmp8) << 8 | tmp8);
02062             } else {
02063                     KdPrint2((PRINT_PREFIX "SII: CacheLine=0 !!!\n"));
02064             }
02065             }
02066             break; }
02067 
02068         case SIICMD: {
02069 
02070             KdPrint2((PRINT_PREFIX "SII_CMD\n"));
02071             if(c == CHAN_NOT_SPECIFIED) {
02072                 /* Setup interrupts. */
02073                 SetPciConfig1(0x71, 0x01);
02074 
02075     /*            GetPciConfig1(0x8a, tmp8);
02076                 tmp8 &= ~(0x30);
02077                 SetPciConfig1(0x71, tmp8);*/
02078 
02079                 /* Use MEMORY READ LINE for reads.
02080                  * NOTE: Although not mentioned in the PCI0646U specs,
02081                  *       these bits are write only and won't be read
02082                  *       back as set or not.  The PCI0646U2 specs clarify
02083                  *       this point.
02084                  */
02085     /*            tmp8 |= 0x02;
02086                 SetPciConfig1(0x71, tmp8);
02087     */
02088                 /* Set reasonable active/recovery/address-setup values. */
02089                 SetPciConfig1(0x53, 0x40);
02090                 SetPciConfig1(0x54, 0x3f);
02091                 SetPciConfig1(0x55, 0x40);
02092                 SetPciConfig1(0x56, 0x3f);
02093                 SetPciConfig1(0x57, 0x1c);
02094                 SetPciConfig1(0x58, 0x3f);
02095                 SetPciConfig1(0x5b, 0x3f);
02096             }
02097 
02098             break; }
02099         }
02100         break;
02101     case ATA_SIS_ID:
02102         if(c == CHAN_NOT_SPECIFIED) {
02103             switch(ChipType) {
02104             case SIS33:
02105                 break;
02106             case SIS66:
02107             case SIS100OLD:
02108                 ChangePciConfig1(0x52, (a & ~0x04));
02109                 break;
02110             case SIS100NEW:
02111             case SIS133OLD:
02112                 ChangePciConfig1(0x49, (a & ~0x01));
02113                 break;
02114             case SIS133NEW:
02115                 ChangePciConfig2(0x50, (a | 0x0008));
02116                 ChangePciConfig2(0x52, (a | 0x0008));
02117                 break;
02118             case SISSATA:
02119                 ChangePciConfig2(0x04, (a & ~0x0400));
02120             }
02121         }
02122         if(ChipType == SIS133NEW) {
02123             USHORT tmp16;
02124             // check 80-pin cable
02125             if(c == CHAN_NOT_SPECIFIED) {
02126                 // do nothing
02127             } else {
02128                 chan = &deviceExtension->chan[c];
02129                 GetPciConfig2(channel ? 0x52 : 0x50, tmp16);
02130                 if(tmp16 & 0x8000) {
02131                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
02132                 }
02133             }
02134         } else {
02135             // check 80-pin cable
02136             if(c == CHAN_NOT_SPECIFIED) {
02137                 // do nothing
02138             } else {
02139                 chan = &deviceExtension->chan[c];
02140                 GetPciConfig1(48, tmp8);
02141                 if(tmp8 & (0x10 << channel)) {
02142                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
02143                 }
02144             }
02145         }
02146         break;
02147     case ATA_VIA_ID:
02148 
02149 /*        if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI | VIASATA) {
02150             break;
02151         }*/
02152         if(c == CHAN_NOT_SPECIFIED) {
02153             /* prepare for ATA-66 on the 82C686a and 82C596b */
02154             if(ChipFlags & VIACLK) {
02155                 ChangePciConfig4(0x50, (a | 0x030b030b));
02156             }
02157             // no init for SATA
02158             if(ChipFlags & (UNIATA_SATA | VIASATA)) {
02159                 /* enable PCI interrupt */
02160                 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
02161                 break;
02162             }
02163 
02164             /* the southbridge might need the data corruption fix */
02165             if(ChipFlags & VIABUG) {
02166                 AtapiViaSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
02167                                          SystemIoBusNumber, slotNumber);
02168             }
02169             /* set prefetch, postwrite */
02170             if(ChipType != VIA133) {
02171                 ChangePciConfig1(0x41, (a | 0xf0));
02172             }
02173 
02174             /* set fifo configuration half'n'half */
02175             ChangePciConfig1(0x43, ((a & ((ChipFlags & VIAPRQ) ? 0x80 : 0x90)) | 0x2a));
02176 
02177             /* set status register read retry */
02178             ChangePciConfig1(0x44, (a | 0x08));
02179 
02180             /* set DMA read & end-of-sector fifo flush */
02181             ChangePciConfig1(0x46, ((a & 0x0c) | 0xf0));
02182 
02183             /* set sector size */
02184             SetPciConfig2(0x60, DEV_BSIZE);
02185             SetPciConfig2(0x68, DEV_BSIZE);
02186         } else {
02187 
02188             chan = &deviceExtension->chan[c];
02189             // no init for SATA
02190             if(ChipFlags & (UNIATA_SATA | VIASATA)) {
02191                 if((ChipFlags & VIABAR) && (c >= 2)) {
02192                     break;
02193                 }
02194                 UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
02195                 break;
02196             }
02197 
02198             // check 80-pin cable
02199             if(!via_cable80(deviceExtension, channel)) {
02200                 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
02201             }
02202         }
02203 
02204         break;
02205 
02206     case ATA_ITE_ID:
02207         if(ChipType == ITE_33 || ChipType == ITE_133_NEW) {
02208             break;
02209         }
02210         if(ChipType == ITE_133) {
02211             if(c == CHAN_NOT_SPECIFIED) {
02212                 /* set PCI mode and 66Mhz reference clock */
02213                 ChangePciConfig1(0x50, a & ~0x83);
02214 
02215                 /* set default active & recover timings */
02216                 SetPciConfig1(0x54, 0x31);
02217                 SetPciConfig1(0x56, 0x31);
02218             } else {
02219                 // check 80-pin cable
02220                 GetPciConfig2(0x40, tmp16);
02221                 chan = &deviceExtension->chan[c];
02222                 if(!(tmp16 & (channel ? 0x08 : 0x04))) {
02223                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
02224                 }
02225             }
02226         } else
02227         if(ChipType == ITE_133_NEW) {
02228         }
02229         break;
02230     default:
02231         if(c != CHAN_NOT_SPECIFIED) {
02232             // We don't know how to check for 80-pin cable on unknown controllers.
02233             // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
02234             // So, leave this flag to use as hint in error recovery procedures
02235             KdPrint2((PRINT_PREFIX "UNIATA_NO80CHK\n"));
02236             deviceExtension->HwFlags |= UNIATA_NO80CHK;
02237         }
02238         break;
02239     }
02240 
02241     // In all places separate channels are inited after common controller init
02242     // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
02243     if(CheckCable && !(ChipFlags & (UNIATA_NO80CHK | UNIATA_SATA))) {
02244         for(c=0; c<deviceExtension->NumberChannels; c++) {
02245             AtapiChipInit(HwDeviceExtension, DeviceNumber, c);
02246         }
02247     }
02248 
02249     return TRUE;
02250 } // end AtapiChipInit()
02251 
02252 VOID
02253 NTAPI
02254 UniataInitMapBM(
02255     IN PHW_DEVICE_EXTENSION deviceExtension,
02256     IN PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0,
02257     IN BOOLEAN MemIo
02258     )
02259 {
02260     PHW_CHANNEL chan;
02261     ULONG c;
02262     ULONG i;
02263 
02264     if(!BaseIoAddressBM_0) {
02265         MemIo = FALSE;
02266     }
02267     for(c=0; c<deviceExtension->NumberChannels; c++) {
02268         chan = &deviceExtension->chan[c];
02269         for (i=0; i<IDX_BM_IO_SZ; i++) {
02270             chan->RegTranslation[IDX_BM_IO+i].Addr  = BaseIoAddressBM_0 ? ((ULONGIO_PTR)BaseIoAddressBM_0 + i) : 0;
02271             chan->RegTranslation[IDX_BM_IO+i].MemIo = MemIo;
02272         }
02273         if(BaseIoAddressBM_0) {
02274             BaseIoAddressBM_0++;
02275         }
02276     }
02277 } // end UniataInitMapBM()
02278 
02279 VOID
02280 NTAPI
02281 UniataInitMapBase(
02282     IN PHW_CHANNEL chan,
02283     IN PIDE_REGISTERS_1 BaseIoAddress1,
02284     IN PIDE_REGISTERS_2 BaseIoAddress2
02285     )
02286 {
02287     ULONG i;
02288 
02289     for (i=0; i<IDX_IO1_SZ; i++) {
02290         chan->RegTranslation[IDX_IO1+i].Addr = BaseIoAddress1 ? ((ULONGIO_PTR)BaseIoAddress1 + i) : 0;
02291         chan->RegTranslation[IDX_IO1+i].MemIo = FALSE;
02292     }
02293     for (i=0; i<IDX_IO2_SZ; i++) {
02294         chan->RegTranslation[IDX_IO2+i].Addr = BaseIoAddress2 ? ((ULONGIO_PTR)BaseIoAddress2 + i) : 0;
02295         chan->RegTranslation[IDX_IO2+i].MemIo = FALSE;
02296     }
02297     UniataInitSyncBaseIO(chan);
02298 } // end UniataInitMapBase()
02299 
02300 VOID
02301 NTAPI
02302 UniataInitSyncBaseIO(
02303     IN PHW_CHANNEL chan
02304     )
02305 {
02306     RtlCopyMemory(&chan->RegTranslation[IDX_IO1_o], &chan->RegTranslation[IDX_IO1], IDX_IO1_SZ*sizeof(chan->RegTranslation[0]));
02307     RtlCopyMemory(&chan->RegTranslation[IDX_IO2_o], &chan->RegTranslation[IDX_IO2], IDX_IO2_SZ*sizeof(chan->RegTranslation[0]));
02308 } // end UniataInitSyncBaseIO()
02309 
02310 VOID
02311 NTAPI
02312 AtapiSetupLunPtrs(
02313     IN PHW_CHANNEL chan,
02314     IN PHW_DEVICE_EXTENSION deviceExtension,
02315     IN ULONG c
02316     )
02317 {
02318     ULONG i;
02319 
02320     if(!deviceExtension->NumberLuns) {
02321         deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN;
02322     }
02323     chan->DeviceExtension = deviceExtension;
02324     chan->lChannel        = c;
02325     chan->NumberLuns      = deviceExtension->NumberLuns;
02326     for(i=0; i<deviceExtension->NumberLuns; i++) {
02327         chan->lun[i] = &(deviceExtension->lun[c*deviceExtension->NumberLuns+i]);
02328     }
02329     chan->AltRegMap       = deviceExtension->AltRegMap;
02330     chan->NextDpcChan     = -1;
02331     for(i=0; i<deviceExtension->NumberLuns; i++) {
02332         chan->lun[i]->DeviceExtension = deviceExtension;
02333         chan->lun[i]->chan            = chan;
02334         chan->lun[i]->Lun             = i;
02335     }
02336 } // end AtapiSetupLunPtrs()
02337 

Generated on Fri May 25 2012 04:26:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.