Index: drivers/storage/ide/uniata/bm_devs.h =================================================================== --- drivers/storage/ide/uniata/bm_devs.h (revision 50961) +++ drivers/storage/ide/uniata/bm_devs.h (working copy) @@ -31,9 +31,12 @@ --*/ -#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 @@ 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: drivers/storage/ide/uniata/bsmaster.h =================================================================== --- drivers/storage/ide/uniata/bsmaster.h (revision 50961) +++ drivers/storage/ide/uniata/bsmaster.h (working copy) @@ -95,6 +95,8 @@ #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 @@ } CAP; #define AHCI_CAP_NOP_MASK 0x0000001f +#define AHCI_CAP_SPM 0x00010000 #define AHCI_CAP_S64A 0x80000000 // Global HBA Control @@ -793,8 +796,11 @@ // 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; ULONG DB_PRD_PhAddr; @@ -898,7 +904,8 @@ // 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,13 @@ #define GET_LDEV2(P, T, L) (T | ((P)<<1)) #define GET_CDEV(Srb) (Srb->TargetId) +VOID +AtapiSetupLunPtrs( + IN PHW_CHANNEL chan, + IN PHW_DEVICE_EXTENSION deviceExtension, + IN ULONG c + ); +/* #define AtapiSetupLunPtrs(chan, deviceExtension, c) \ { \ chan->DeviceExtension = deviceExtension; \ @@ -1504,7 +1518,7 @@ chan->lun[0]->DeviceExtension = deviceExtension; \ chan->lun[1]->DeviceExtension = deviceExtension; \ } - +*/ BOOLEAN NTAPI AtapiReadChipConfig( Index: drivers/storage/ide/uniata/id_ata.cpp =================================================================== --- drivers/storage/ide/uniata/id_ata.cpp (revision 50961) +++ drivers/storage/ide/uniata/id_ata.cpp (working copy) @@ -2976,8 +2976,8 @@ 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 @@ &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 @@ 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: drivers/storage/ide/uniata/id_init.cpp =================================================================== --- drivers/storage/ide/uniata/id_init.cpp (revision 50961) +++ drivers/storage/ide/uniata/id_init.cpp (working copy) @@ -68,6 +68,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ 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; iNumberLuns; i++) { + UniAtaReadLunConfig(deviceExtension, channel, i); + } } return TRUE; @@ -1656,25 +1646,104 @@ } 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; cNumberChannels; c++) { + KdPrint2((PRINT_PREFIX "i indexed\n")); + //for(c=0; cNumberChannels; 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 @@ 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; iNumberLuns; i++) { + chan->lun[i] = &(deviceExtension->lun[c*deviceExtension->NumberLuns+i]); + } + chan->AltRegMap = deviceExtension->AltRegMap; + chan->NextDpcChan = -1; + for(i=0; iNumberLuns; i++) { + chan->lun[i]->DeviceExtension = deviceExtension; + } +} // end AtapiSetupLunPtrs() + Index: drivers/storage/ide/uniata/id_probe.cpp =================================================================== --- drivers/storage/ide/uniata/id_probe.cpp (revision 50961) +++ drivers/storage/ide/uniata/id_probe.cpp (working copy) @@ -145,6 +145,11 @@ 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 @@ BOOLEAN found; BOOLEAN known; + BOOLEAN NeedPciAltInit; UCHAR IrqForCompat = 10; @@ -269,6 +275,7 @@ for(pass=0; pass<3; pass++) { for(busNumber=0 ;busNumberMasterDev = 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 @@ } } - 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 @@ 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 @@ } 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 @@ 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 @@ (*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 @@ 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 @@ 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 @@ } 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 @@ // 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: drivers/storage/ide/uniata/id_sata.cpp =================================================================== --- drivers/storage/ide/uniata/id_sata.cpp (revision 50961) +++ drivers/storage/ide/uniata/id_sata.cpp (working copy) @@ -380,33 +380,65 @@ 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); + 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); - if(CAP & AHCI_CAP_S64A) { - KdPrint2((PRINT_PREFIX " AHCI 64bit\n")); - deviceExtension->Host64 = TRUE; - } + 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, AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_IS)); @@ -416,10 +448,13 @@ 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: drivers/storage/ide/uniata/uata_ctl.h =================================================================== --- drivers/storage/ide/uniata/uata_ctl.h (revision 50961) +++ drivers/storage/ide/uniata/uata_ctl.h (working copy) @@ -43,9 +43,9 @@ #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: drivers/storage/ide/uniata/uniata_ver.h =================================================================== --- drivers/storage/ide/uniata/uniata_ver.h (revision 50961) +++ drivers/storage/ide/uniata/uniata_ver.h (working copy) @@ -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"