[UNIATA]
authorAleksey Bragin <aleksey@reactos.org>
Sun, 6 Mar 2011 16:32:36 +0000 (16:32 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Sun, 6 Mar 2011 16:32:36 +0000 (16:32 +0000)
- Rafal Harabien: Sync UniATA to 0.40a5. Changelog:
* Fixed bug with BSOD on newer SATA/AHCI Intel chips.
* Added support for different number of devices on different channls.
* Updated AHCI support code (not ready yet).
* All ReactOS specific changes have been left.
See issue #5976 for more details.

svn path=/trunk/; revision=50985

reactos/drivers/storage/ide/uniata/bm_devs.h
reactos/drivers/storage/ide/uniata/bsmaster.h
reactos/drivers/storage/ide/uniata/id_ata.cpp
reactos/drivers/storage/ide/uniata/id_init.cpp
reactos/drivers/storage/ide/uniata/id_probe.cpp
reactos/drivers/storage/ide/uniata/id_sata.cpp
reactos/drivers/storage/ide/uniata/uata_ctl.h
reactos/drivers/storage/ide/uniata/uniata_ver.h

index dbcbfa9..672b22a 100644 (file)
@@ -31,9 +31,12 @@ Revision History:
 
 --*/
 
-#define IDE_MAX_CHAN          8
+#define IDE_MAX_CHAN          16
+#define IDE_DEFAULT_MAX_CHAN  2
 // Thanks to SATA Port Multipliers:
-#define IDE_MAX_LUN_PER_CHAN  16
+//#define IDE_MAX_LUN_PER_CHAN  SATA_MAX_PM_UNITS
+#define IDE_MAX_LUN_PER_CHAN  2
+
 #define IDE_MAX_LUN           (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN)
 
 #define MAX_QUEUE_STAT        8
@@ -113,6 +116,7 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
     ULONG      Isr2Vector;
     PKINTERRUPT Isr2InterruptObject;
     CHAR    AltInitMasterDev;       // 0xff - uninitialized,  0x00 - normal,  0x01 - change ISA to PCI
+       CHAR    NeedAltInit;            // 0x01 - try change ISA to PCI
 #endif
 
 }BUSMASTER_CONTROLLER_INFORMATION, *PBUSMASTER_CONTROLLER_INFORMATION;
index 365f076..0626b2c 100644 (file)
@@ -95,6 +95,8 @@ Revision History:
 
 #define AHCI_MAX_PORT                   32
 
+#define SATA_MAX_PM_UNITS               16
+
 typedef struct _BUSMASTER_CTX {
     PBUSMASTER_CONTROLLER_INFORMATION* BMListPtr;
     ULONG* BMListLen;
@@ -178,6 +180,7 @@ typedef struct _IDE_AHCI_REGISTERS {
     } CAP;
 
 #define AHCI_CAP_NOP_MASK    0x0000001f
+#define AHCI_CAP_SPM         0x00010000
 #define AHCI_CAP_S64A        0x80000000
 
     // Global HBA Control
@@ -793,7 +796,10 @@ typedef struct _HW_CHANNEL {
 //    KIRQL               QueueOldIrql;
 #endif
     struct _HW_DEVICE_EXTENSION* DeviceExtension;
-    struct _HW_LU_EXTENSION* lun[2];
+    struct _HW_LU_EXTENSION* lun[IDE_MAX_LUN_PER_CHAN];
+
+    ULONG   NumberLuns;
+    ULONG   PmLunMap;
 
     // Double-buffering support
     PVOID   DB_PRD;
@@ -898,7 +904,8 @@ typedef struct _HW_LU_EXTENSION {
     // Controller-specific LUN options
     union {
         /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
-           mainly for mapping SATA ports to compatible PATA registers */
+           Treated as PHYSICAL port number, regardless of logical mapping.
+         */
         ULONG          SATA_lun_map; 
     };
 
@@ -1493,6 +1500,14 @@ AtapiReadBuffer2(
 #define GET_LDEV2(P, T, L)  (T | ((P)<<1))
 #define GET_CDEV(Srb)  (Srb->TargetId)
 
+VOID
+NTAPI
+AtapiSetupLunPtrs(
+    IN PHW_CHANNEL chan,
+    IN PHW_DEVICE_EXTENSION deviceExtension,
+    IN ULONG c
+    );
+/*
 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
 { \
         chan->DeviceExtension = deviceExtension; \
@@ -1504,7 +1519,7 @@ AtapiReadBuffer2(
         chan->lun[0]->DeviceExtension = deviceExtension; \
         chan->lun[1]->DeviceExtension = deviceExtension; \
 }
-
+*/
 BOOLEAN
 NTAPI
 AtapiReadChipConfig(
index 70aaed3..07c4425 100644 (file)
@@ -2976,8 +2976,8 @@ ContinueSearch:
 
     kptr = KeyWord;
     while ((*cptr == *kptr) ||
-           (*cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
-           (*cptr >= 'a' && *cptr - ('a' - 'A') == *kptr)) {
+           (*cptr >= 'A' && *cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
+           (*cptr >= 'a' && *cptr <= 'z' && *cptr - ('a' - 'A') == *kptr)) {
         cptr++;
         kptr++;
 
@@ -8589,6 +8589,16 @@ DriverEntry(
                                                &hwInitializationData.comm,
                                                (PVOID)(i | (alt ? 0x80000000 : 0)));
                 KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
+                if(newStatus == (ULONG)STATUS_DEVICE_DOES_NOT_EXIST && BMList[i].NeedAltInit) {
+                    KdPrint2((PRINT_PREFIX "STATUS_DEVICE_DOES_NOT_EXIST, try workaround\n"));
+                    hwInitializationData.comm.AdapterInterfaceType = Isa;
+                    newStatus = ScsiPortInitialize(DriverObject,
+                                               Argument2,
+                                               &hwInitializationData.comm,
+                                               (PVOID)(i | 0x80000000));
+                    KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x (2)\n", newStatus));
+                               }
+
                 if (newStatus < statusToReturn) {
                     statusToReturn = newStatus;
                 }
@@ -9090,7 +9100,7 @@ AtapiRegCheckParameterValue(
 
     status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
                                     paramPath.Buffer, parameters, NULL, NULL);
-    //KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
+    KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
 
     ExFreePool(paramPath.Buffer);
 
index 526a60d..8126599 100644 (file)
@@ -68,6 +68,11 @@ UniataChipDetectChannels(
         deviceExtension->NumberChannels = 1;
     }
 
+    if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
+        KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
+        //deviceExtension->NumberLuns = SATA_MAX_PM_UNITS;
+    }
+
     switch(VendorID) {
     case ATA_ACER_LABS_ID:
         switch(deviceExtension->DevID) {
@@ -102,8 +107,8 @@ UniataChipDetectChannels(
     case ATA_ATI_ID:
         KdPrint2((PRINT_PREFIX "ATI\n"));
         switch(deviceExtension->DevID) {
-        case 0x438c1002: 
-        case 0x439c1002:
+        case ATA_ATI_IXP600:    
+        case ATA_ATI_IXP700:
             /* IXP600 & IXP700 only have 1 PATA channel */
             if(BMList[deviceExtension->DevIndex].channel) {
                 KdPrint2((PRINT_PREFIX "New ATI no 2nd PATA chan\n"));
@@ -142,6 +147,12 @@ UniataChipDetectChannels(
             deviceExtension->NumberChannels = 3;
             KdPrint2((PRINT_PREFIX "VIA 3 chan\n"));
         }
+        if(ChipFlags & VIASATA) {
+            /* 2 SATA without SATA registers on first channel + 1 PATA on second */
+            // do nothing, generic PATA INIT
+            KdPrint2((PRINT_PREFIX "VIA SATA without SATA regs -> no PM\n"));
+            deviceExtension->NumberLuns = SATA_MAX_PM_UNITS;
+        }
         break;
     case ATA_ITE_ID:
         /* ITE ATA133 controller */
@@ -981,32 +992,14 @@ for_ugly_chips:
                 IsPata = FALSE;
                 if(ChipFlags & ICH5) {
                     if ((tmp8 & 0x04) == 0) {
-                        //ch->flags |= ATA_SATA;
-                        //ch->flags |= ATA_NO_SLAVE;
-                        //smap[0] = (map & 0x01) ^ ch->unit;
-                        //smap[1] = 0;
                         chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
-                        chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ^ c;
-                        chan->lun[1]->SATA_lun_map = 0;
                     } else if ((tmp8 & 0x02) == 0) {
-                               //ch->flags |= ATA_SATA;
-                               //smap[0] = (map & 0x01) ? 1 : 0;
-                               //smap[1] = (map & 0x01) ? 0 : 1;
-                        if(c == 0) {
-                            chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
-                            chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
-                        } else {
+                        if(c != 0) {
                             IsPata = TRUE;
                             //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
                         }
                     } else if ((tmp8 & 0x02) != 0) {
-                               //ch->flags |= ATA_SATA;
-                               //smap[0] = (map & 0x01) ? 1 : 0;
-                               //smap[1] = (map & 0x01) ? 0 : 1;
-                        if(c == 1) {
-                            chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
-                            chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
-                        } else {
+                        if(c != 1) {
                             IsPata = TRUE;
                             //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
                         }
@@ -1014,28 +1007,16 @@ for_ugly_chips:
                 } else
                 if(ChipFlags & I6CH2) {
                     chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
-                    chan->lun[0]->SATA_lun_map = c ? 4 : 5;
-                    chan->lun[1]->SATA_lun_map = 0;
                 } else {
                     switch(tmp8 & 0x03) {
-                    case 0:
-                        chan->lun[0]->SATA_lun_map = 0+c;
-                        chan->lun[1]->SATA_lun_map = 2+c;
-                        break;
                     case 2:
-                        if(c==0) {
-                            chan->lun[0]->SATA_lun_map = 0;
-                            chan->lun[1]->SATA_lun_map = 2;
-                        } else {
+                                               if(c!=0) {
                             // PATA
                             IsPata = TRUE;
                         }
                         break;
                     case 1:
-                        if(c==1) {
-                            chan->lun[0]->SATA_lun_map = 1;
-                            chan->lun[1]->SATA_lun_map = 3;
-                        } else {
+                        if(c!=1) {
                             // PATA
                             IsPata = TRUE;
                         }
@@ -1045,9 +1026,11 @@ for_ugly_chips:
 
                 if(IsPata) {
                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
+                    KdPrint2((PRINT_PREFIX "PATA part\n"));
                 } else {
 
                     if((ChipFlags & ICH5) && BaseMemAddress) {
+                        KdPrint2((PRINT_PREFIX "ICH5 indexed\n"));
                         chan->RegTranslation[IDX_INDEXED_ADDR].Addr        = BaseMemAddress + 0;
                         chan->RegTranslation[IDX_INDEXED_ADDR].MemIo       = MemIo;
                         chan->RegTranslation[IDX_INDEXED_DATA].Addr        = BaseMemAddress + 4;
@@ -1055,6 +1038,7 @@ for_ugly_chips:
                     }
                     if((ChipFlags & ICH5) || BaseMemAddress) {
 
+                        KdPrint2((PRINT_PREFIX "i indexed\n"));
                         // Rather interesting way of register access...
                         ChipType = INTEL_IDX;
                         deviceExtension->HwFlags &= ~CHIPTYPE_MASK;
@@ -1085,6 +1069,10 @@ for_ugly_chips:
     }
 
     if(ChipFlags & UNIATA_AHCI) {
+        if(AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhci", 1)) {
+            KdPrint(("  AHCI excluded\n"));
+            return STATUS_UNSUCCESSFUL;
+        }
         return UniataAhciInit(HwDeviceExtension) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
     }
 
@@ -1395,8 +1383,8 @@ UniAtaReadLunConfig(
     c = channel - deviceExtension->Channel; // logical channel
 
     chan = &deviceExtension->chan[c];
-    ldev &= 0x01;
-    LunExt = &(deviceExtension->lun[c*2+ldev]);
+    ldev &= (deviceExtension->NumberLuns-1);
+    LunExt = &(deviceExtension->lun[c*deviceExtension->NumberLuns+ldev]);
 
     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"ReadCacheEnable", 1);
     LunExt->opt_ReadCacheEnable = tmp32 ? TRUE : FALSE;
@@ -1441,6 +1429,7 @@ AtapiReadChipConfig(
     PHW_CHANNEL chan;
     ULONG  tmp32;
     ULONG  c; // logical channel (for Compatible Mode controllers)
+    ULONG  i;
 
     KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: devExt %#x\n", deviceExtension ));
     ASSERT(deviceExtension);
@@ -1504,8 +1493,9 @@ AtapiReadChipConfig(
         tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"ReorderEnable", TRUE);
         chan->UseReorder = tmp32 ? TRUE : FALSE;
 
-        UniAtaReadLunConfig(deviceExtension, channel, 0);
-        UniAtaReadLunConfig(deviceExtension, channel, 1);
+        for(i=0; i<deviceExtension->NumberLuns; i++) {
+            UniAtaReadLunConfig(deviceExtension, channel, i);
+        }
     }
 
     return TRUE;
@@ -1656,25 +1646,104 @@ AtapiChipInit(
         }
         break;
     case ATA_INTEL_ID: {
+        BOOLEAN IsPata;
         USHORT reg54;
+        UCHAR tmp8;
         if(ChipFlags & UNIATA_SATA) {
 
-            if(ChipFlags & UNIATA_AHCI)
+            KdPrint2((PRINT_PREFIX "Intel SATA\n"));
+            if(ChipFlags & UNIATA_AHCI) {
+                KdPrint2((PRINT_PREFIX "Skip AHCI\n"));
                 break;
+            }
             if(c == CHAN_NOT_SPECIFIED) {
+                KdPrint2((PRINT_PREFIX "Base init\n"));
                 /* force all ports active "the legacy way" */
                 ChangePciConfig2(0x92, (a | 0x0f));
                 /* enable PCI interrupt */
                 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
+
             } else {
+
+                KdPrint2((PRINT_PREFIX "channel init\n"));
+
+                GetPciConfig1(0x90, tmp8);
+                KdPrint2((PRINT_PREFIX "reg 90: %x, init lun map\n", tmp8));
+
+                KdPrint2((PRINT_PREFIX "chan %d\n", c));
+                chan = &deviceExtension->chan[c];
+                IsPata = FALSE;
+                if(ChipFlags & ICH5) {
+                    KdPrint2((PRINT_PREFIX "ICH5\n"));
+                    if ((tmp8 & 0x04) == 0) {
+                        chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
+                        chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ^ c;
+                        chan->lun[1]->SATA_lun_map = 0;
+                    } else if ((tmp8 & 0x02) == 0) {
+                        if(c == 0) {
+                            chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
+                            chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
+                        } else {
+                            IsPata = TRUE;
+                            //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
+                        }
+                    } else if ((tmp8 & 0x02) != 0) {
+                        if(c == 1) {
+                            chan->lun[0]->SATA_lun_map = (tmp8 & 0x01) ? 1 : 0;
+                            chan->lun[1]->SATA_lun_map = (tmp8 & 0x01) ? 0 : 1;
+                        } else {
+                            IsPata = TRUE;
+                            //chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
+                        }
+                    }
+                } else
+                if(ChipFlags & I6CH2) {
+                    KdPrint2((PRINT_PREFIX "I6CH2\n"));
+                    chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
+                    chan->lun[0]->SATA_lun_map = c ? 4 : 5;
+                    chan->lun[1]->SATA_lun_map = 0;
+                } else {
+                    KdPrint2((PRINT_PREFIX "other Intel\n"));
+                    switch(tmp8 & 0x03) {
+                    case 0:
+                        chan->lun[0]->SATA_lun_map = 0+c;
+                        chan->lun[1]->SATA_lun_map = 2+c;
+                        break;
+                    case 2:
+                        if(c==0) {
+                            chan->lun[0]->SATA_lun_map = 0;
+                            chan->lun[1]->SATA_lun_map = 2;
+                        } else {
+                            // PATA
+                            IsPata = TRUE;
+                        }
+                        break;
+                    case 1:
+                        if(c==1) {
+                            chan->lun[0]->SATA_lun_map = 1;
+                            chan->lun[1]->SATA_lun_map = 3;
+                        } else {
+                            // PATA
+                            IsPata = TRUE;
+                        }
+                        break;
+                    }
+                }
+
+                if(IsPata) {
+                    KdPrint2((PRINT_PREFIX "PATA part\n"));
+                    chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
+                }
+
                 if(ChipType == INTEL_IDX) {
-                    for(c=0; c<deviceExtension->NumberChannels; c++) {
+                    KdPrint2((PRINT_PREFIX "i indexed\n"));
+                    //for(c=0; c<deviceExtension->NumberChannels; c++) {
                         chan = &deviceExtension->chan[c];
                         UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
                         if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
                             UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 1);
                         }
-                    }
+                    //}
                 }
             }
 
@@ -2141,3 +2210,30 @@ UniataInitSyncBaseIO(
     RtlCopyMemory(&chan->RegTranslation[IDX_IO1_o], &chan->RegTranslation[IDX_IO1], IDX_IO1_SZ*sizeof(chan->RegTranslation[0]));
     RtlCopyMemory(&chan->RegTranslation[IDX_IO2_o], &chan->RegTranslation[IDX_IO2], IDX_IO2_SZ*sizeof(chan->RegTranslation[0]));
 } // end UniataInitSyncBaseIO()
+
+VOID
+NTAPI
+AtapiSetupLunPtrs(
+    IN PHW_CHANNEL chan,
+    IN PHW_DEVICE_EXTENSION deviceExtension,
+    IN ULONG c
+    )
+{
+    ULONG i;
+
+    if(!deviceExtension->NumberLuns) {
+        deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN;
+    }
+    chan->DeviceExtension = deviceExtension;
+    chan->lChannel        = c;
+    chan->NumberLuns      = deviceExtension->NumberLuns;
+    for(i=0; i<deviceExtension->NumberLuns; i++) {
+        chan->lun[i] = &(deviceExtension->lun[c*deviceExtension->NumberLuns+i]);
+    }
+    chan->AltRegMap       = deviceExtension->AltRegMap;
+    chan->NextDpcChan     = -1;
+    for(i=0; i<deviceExtension->NumberLuns; i++) {
+        chan->lun[i]->DeviceExtension = deviceExtension;
+    }
+} // end AtapiSetupLunPtrs()
+
index 2752b2a..00eab9b 100644 (file)
@@ -145,6 +145,11 @@ AtapiGetIoRange(
                 ScsiPortConvertUlongToPhysicalAddress(io_start);
             (*ConfigInfo->AccessRanges)[rid].RangeLength = length;
         }
+        if((pciData->u.type0.BaseAddresses[rid] & PCI_ADDRESS_IO_SPACE)) {
+            (*ConfigInfo->AccessRanges)[rid].RangeInMemory = FALSE;
+        } else {
+            (*ConfigInfo->AccessRanges)[rid].RangeInMemory = TRUE;
+        }
     } else {
         io_start = 0;
     }
@@ -252,6 +257,7 @@ UniataEnumBusMasterController__(
 
     BOOLEAN found;
     BOOLEAN known;
+    BOOLEAN NeedPciAltInit;
 
     UCHAR IrqForCompat = 10;
 
@@ -269,6 +275,7 @@ UniataEnumBusMasterController__(
     for(pass=0; pass<3; pass++) {
         for(busNumber=0 ;busNumber<maxPciBus && !no_buses; busNumber++) {
             for(slotNumber=0; slotNumber<PCI_MAX_DEVICES  && !no_buses; slotNumber++) {
+            NeedPciAltInit = FALSE;
             for(funcNumber=0; funcNumber<PCI_MAX_FUNCTION && !no_buses; funcNumber++) {
 
 //                KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
@@ -288,11 +295,15 @@ UniataEnumBusMasterController__(
                     break;
                 }
                 // no device in this slot
-                if(busDataRead == 2)
+                               if(busDataRead == 2) {
+                    NeedPciAltInit = TRUE;
                     continue;
+                }
 
-                if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH)
+                if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
+                    NeedPciAltInit = TRUE;
                     continue;
+                }
 
                 VendorID  = pciData.VendorID;
                 DeviceID  = pciData.DeviceID;
@@ -304,6 +315,7 @@ UniataEnumBusMasterController__(
                 if(BaseClass != PCI_DEV_CLASS_STORAGE)
                     continue;
 
+                KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
                 KdPrint2((PRINT_PREFIX "Storage Class\n"));
                 KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
                 // look for known chipsets
@@ -528,9 +540,10 @@ UniataEnumBusMasterController__(
                         newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0;
                         newBMListPtr->busNumber = busNumber;
 
+                        newBMListPtr->NeedAltInit = NeedPciAltInit;
                         newBMListPtr->Known = known;
 
-                        KdPrint2((PRINT_PREFIX "Add to BMList\n"));
+                        KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit));
                     } else {
                         KdPrint2((PRINT_PREFIX "count: BMListLen++\n"));
                     }
@@ -812,12 +825,12 @@ UniataAllocateLunExt(
         }
     }
 
-    deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * IDE_MAX_LUN_PER_CHAN);
+    deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
     if (!deviceExtension->lun) {
         KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
         return FALSE;
     }
-    RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * IDE_MAX_LUN_PER_CHAN);
+    RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
     
     deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
     if (!deviceExtension->chan) {
@@ -1025,7 +1038,8 @@ UniataFindBusMasterController(
     deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
     deviceExtension->DevID = dev_id;
     deviceExtension->RevID = RevID;
-    deviceExtension->NumberChannels = 2; // default
+    deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; // default
+    deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
     deviceExtension->DevIndex = i;
 
     _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
@@ -1266,9 +1280,9 @@ UniataFindBusMasterController(
     }
 
     if(simplexOnly && MasterDev) {
-        if(deviceExtension->NumberChannels < 2) {
-            KdPrint2((PRINT_PREFIX "set NumberChannels = 2\n"));
-            deviceExtension->NumberChannels = 2;
+        if(deviceExtension->NumberChannels < IDE_DEFAULT_MAX_CHAN) {
+            KdPrint2((PRINT_PREFIX "set NumberChannels = %d\n", IDE_DEFAULT_MAX_CHAN));
+            deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN;
             if(BaseIoAddressBM_0) {
                 UniataInitMapBM(deviceExtension,
                                 BaseIoAddressBM_0,
@@ -1289,7 +1303,7 @@ UniataFindBusMasterController(
         KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0]));
     }
     // Indicate four devices can be attached to the adapter
-    ConfigInfo->MaximumNumberOfTargets = (UCHAR)(/*deviceExtension->NumberChannels **/ 2);
+    ConfigInfo->MaximumNumberOfTargets = (UCHAR)(deviceExtension->NumberLuns);
 
     if (MasterDev) {
         KdPrint2((PRINT_PREFIX "MasterDev (2)\n"));
@@ -1461,6 +1475,15 @@ UniataFindBusMasterController(
                     (*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
                     (*ConfigInfo->AccessRanges)[4].RangeLength = 0;
                 }
+            } else
+            if(AltInit &&
+               !(*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart.QuadPart &&
+               !(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart.QuadPart) {
+                KdPrint2((PRINT_PREFIX "cheat ScsiPort, sync real PCI and ConfigInfo IO ranges\n"));
+                AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber,
+                        channel * 2 + 0, 0, ATA_IOSIZE);
+                AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber,
+                        channel * 2 + 1, 0, ATA_ALTIOSIZE);
             }
 
             IoBasePort1 = (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart;
@@ -1860,7 +1883,8 @@ UniataFindFakeBusMasterController(
     deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
     deviceExtension->DevID = dev_id;
     deviceExtension->RevID = RevID;
-    deviceExtension->NumberChannels = 2; // default
+    deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; // default
+    deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
     deviceExtension->DevIndex = i;
 
     _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
@@ -2291,6 +2315,7 @@ AtapiFindController(
     KdPrint2((PRINT_PREFIX "  assume max PIO4\n"));
     deviceExtension->MaxTransferMode = ATA_PIO4;
     deviceExtension->NumberChannels = 1;
+    deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
 
     if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
         goto exit_error;
@@ -2525,7 +2550,7 @@ not_found:
         }
 
         ConfigInfo->NumberOfBuses = 1;
-        ConfigInfo->MaximumNumberOfTargets = 2;
+        ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN;
 
         // Indicate maximum transfer length is 64k.
         ConfigInfo->MaximumTransferLength = 0x10000;
@@ -2970,7 +2995,7 @@ FindDevices(
     // Clear expecting interrupt flag and current SRB field.
     chan->ExpectingInterrupt = FALSE;
 //    chan->CurrentSrb = NULL;
-    max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2;
+    max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
     KdPrint2((PRINT_PREFIX "  max_ldev %d\n", max_ldev));
 
     // Search for devices.
index c6dd47d..7ab242a 100644 (file)
@@ -380,32 +380,64 @@ UniataAhciInit(
     ULONG BaseMemAddress;
     ULONG PI;
     ULONG CAP;
+    ULONG GHC;
     BOOLEAN MemIo;
     ULONGLONG base;
 
     /* reset AHCI controller */
-    AtapiWritePortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC,
-        AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) | AHCI_GHC_HR);
-    AtapiStallExecution(1000000);
-    if(AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) & AHCI_GHC_HR) {
+    GHC = AtapiReadPortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC);
+    KdPrint2((PRINT_PREFIX "  reset AHCI controller, GHC %x\n", GHC));
+    AtapiWritePortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
+        GHC | AHCI_GHC_HR);
+
+    for(i=0; i<1000; i++) {
+        AtapiStallExecution(1000);
+        GHC = AtapiReadPortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC);
+        KdPrint2((PRINT_PREFIX "  AHCI GHC %x\n", GHC));
+        if(!(GHC & AHCI_GHC_HR)) {
+            break;
+        }
+    }
+    if(GHC & AHCI_GHC_HR) {
         KdPrint2((PRINT_PREFIX "  AHCI reset failed\n"));
         return FALSE;
     }
 
     /* enable AHCI mode */
-    AtapiWritePortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC,
-        AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) | AHCI_GHC_AE);
+    GHC = AtapiReadPortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC);
+    KdPrint2((PRINT_PREFIX "  enable AHCI mode, GHC %x\n", GHC));
+    AtapiWritePortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
+        GHC | AHCI_GHC_AE);
+    GHC = AtapiReadPortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC);
+    KdPrint2((PRINT_PREFIX "  AHCI GHC %x\n", GHC));
+
 
     CAP = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_CAP);
     PI = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_PI);
-    /* get the number of HW channels */
-    for(i=PI, n=0; i; n++, i=i>>1);
-    deviceExtension->NumberChannels =
-        max((CAP & AHCI_CAP_NOP_MASK)+1, n);
+    KdPrint2((PRINT_PREFIX "  AHCI CAP %x\n", CAP));
     if(CAP & AHCI_CAP_S64A) {
         KdPrint2((PRINT_PREFIX "  AHCI 64bit\n"));
         deviceExtension->Host64 = TRUE;
     }
+    /* get the number of HW channels */
+    PI = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_PI);
+    KdPrint2((PRINT_PREFIX "  AHCI PI %x\n", PI));
+    for(i=PI, n=0; i; n++, i=i>>1);
+    deviceExtension->NumberChannels =
+        max((CAP & AHCI_CAP_NOP_MASK)+1, n);
+
+    switch(deviceExtension->DevID) {
+    case ATA_M88SX6111:
+        deviceExtension->NumberChannels = 1;
+        break;
+    case ATA_M88SX6121:
+        deviceExtension->NumberChannels = 2;
+        break;
+    case ATA_M88SX6141:
+    case ATA_M88SX6145:
+        deviceExtension->NumberChannels = 4;
+        break;
+    } // switch()
 
     /* clear interrupts */
     AtapiWritePortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_IS,
@@ -416,10 +448,13 @@ UniataAhciInit(
         AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) | AHCI_GHC_IE);
 
     version = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_VS);
-    KdPrint2((PRINT_PREFIX "  AHCI version %x%x.%x%x controller with %d ports (mask %x) detected\n",
-                 (version >> 24) & 0xff, (version >> 16) & 0xff,
-                 (version >> 8) & 0xff, version & 0xff, deviceExtension->NumberChannels, PI));
+        KdPrint2((PRINT_PREFIX "  AHCI version %x.%02x controller with %d ports (mask %x) detected\n",
+                 ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f),
+                 ((version >> 4) & 0xf0) + (version & 0x0f),
+                 deviceExtension->NumberChannels, PI));
 
+    KdPrint2((PRINT_PREFIX "  PM%s supported\n",
+                 CAP & AHCI_CAP_SPM ? "" : " not"));
 
     deviceExtension->HwFlags |= UNIATA_SATA;
     deviceExtension->HwFlags |= UNIATA_AHCI;
index b199d2b..560b1d8 100644 (file)
@@ -43,9 +43,9 @@ extern "C" {
 #endif //__cplusplus
 
 #define AHCI_MAX_PORT                   32
-#define IDE_MAX_CHAN          8
+#define IDE_MAX_CHAN          16
 // Thanks to SATA Port Multipliers:
-#define IDE_MAX_LUN_PER_CHAN  16
+#define IDE_MAX_LUN_PER_CHAN  2
 #define IDE_MAX_LUN           (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN)
 
 #define MAX_QUEUE_STAT        8
index 5cfcf46..381ae7b 100644 (file)
@@ -1,6 +1,6 @@
-#define UNIATA_VER_STR         "40a1"
-#define UNIATA_VER_DOT         0.40.1.1
-#define UNIATA_VER_DOT_COMMA   0,40,1,1
-#define UNIATA_VER_DOT_STR     "0.40.1.1"
+#define UNIATA_VER_STR         "40a5"
+#define UNIATA_VER_DOT         0.40.1.5
+#define UNIATA_VER_DOT_COMMA   0,40,1,5
+#define UNIATA_VER_DOT_STR     "0.40.1.5"
 #define UNIATA_VER_YEAR        2010
 #define UNIATA_VER_YEAR_STR    "2010"