mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 09:20:30 +00:00
[UNIATA]
- 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
This commit is contained in:
parent
f7af2d5aad
commit
a393a04761
8 changed files with 268 additions and 83 deletions
|
@ -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:
|
// 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 IDE_MAX_LUN (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN)
|
||||||
|
|
||||||
#define MAX_QUEUE_STAT 8
|
#define MAX_QUEUE_STAT 8
|
||||||
|
@ -113,6 +116,7 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||||
ULONG Isr2Vector;
|
ULONG Isr2Vector;
|
||||||
PKINTERRUPT Isr2InterruptObject;
|
PKINTERRUPT Isr2InterruptObject;
|
||||||
CHAR AltInitMasterDev; // 0xff - uninitialized, 0x00 - normal, 0x01 - change ISA to PCI
|
CHAR AltInitMasterDev; // 0xff - uninitialized, 0x00 - normal, 0x01 - change ISA to PCI
|
||||||
|
CHAR NeedAltInit; // 0x01 - try change ISA to PCI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}BUSMASTER_CONTROLLER_INFORMATION, *PBUSMASTER_CONTROLLER_INFORMATION;
|
}BUSMASTER_CONTROLLER_INFORMATION, *PBUSMASTER_CONTROLLER_INFORMATION;
|
||||||
|
|
|
@ -95,6 +95,8 @@ Revision History:
|
||||||
|
|
||||||
#define AHCI_MAX_PORT 32
|
#define AHCI_MAX_PORT 32
|
||||||
|
|
||||||
|
#define SATA_MAX_PM_UNITS 16
|
||||||
|
|
||||||
typedef struct _BUSMASTER_CTX {
|
typedef struct _BUSMASTER_CTX {
|
||||||
PBUSMASTER_CONTROLLER_INFORMATION* BMListPtr;
|
PBUSMASTER_CONTROLLER_INFORMATION* BMListPtr;
|
||||||
ULONG* BMListLen;
|
ULONG* BMListLen;
|
||||||
|
@ -178,6 +180,7 @@ typedef struct _IDE_AHCI_REGISTERS {
|
||||||
} CAP;
|
} CAP;
|
||||||
|
|
||||||
#define AHCI_CAP_NOP_MASK 0x0000001f
|
#define AHCI_CAP_NOP_MASK 0x0000001f
|
||||||
|
#define AHCI_CAP_SPM 0x00010000
|
||||||
#define AHCI_CAP_S64A 0x80000000
|
#define AHCI_CAP_S64A 0x80000000
|
||||||
|
|
||||||
// Global HBA Control
|
// Global HBA Control
|
||||||
|
@ -793,7 +796,10 @@ typedef struct _HW_CHANNEL {
|
||||||
// KIRQL QueueOldIrql;
|
// KIRQL QueueOldIrql;
|
||||||
#endif
|
#endif
|
||||||
struct _HW_DEVICE_EXTENSION* DeviceExtension;
|
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
|
// Double-buffering support
|
||||||
PVOID DB_PRD;
|
PVOID DB_PRD;
|
||||||
|
@ -898,7 +904,8 @@ typedef struct _HW_LU_EXTENSION {
|
||||||
// Controller-specific LUN options
|
// Controller-specific LUN options
|
||||||
union {
|
union {
|
||||||
/* for tricky controllers, those can change Logical-to-Physical LUN mapping.
|
/* 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;
|
ULONG SATA_lun_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1493,6 +1500,14 @@ AtapiReadBuffer2(
|
||||||
#define GET_LDEV2(P, T, L) (T | ((P)<<1))
|
#define GET_LDEV2(P, T, L) (T | ((P)<<1))
|
||||||
#define GET_CDEV(Srb) (Srb->TargetId)
|
#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) \
|
#define AtapiSetupLunPtrs(chan, deviceExtension, c) \
|
||||||
{ \
|
{ \
|
||||||
chan->DeviceExtension = deviceExtension; \
|
chan->DeviceExtension = deviceExtension; \
|
||||||
|
@ -1504,7 +1519,7 @@ AtapiReadBuffer2(
|
||||||
chan->lun[0]->DeviceExtension = deviceExtension; \
|
chan->lun[0]->DeviceExtension = deviceExtension; \
|
||||||
chan->lun[1]->DeviceExtension = deviceExtension; \
|
chan->lun[1]->DeviceExtension = deviceExtension; \
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
AtapiReadChipConfig(
|
AtapiReadChipConfig(
|
||||||
|
|
|
@ -2976,8 +2976,8 @@ ContinueSearch:
|
||||||
|
|
||||||
kptr = KeyWord;
|
kptr = KeyWord;
|
||||||
while ((*cptr == *kptr) ||
|
while ((*cptr == *kptr) ||
|
||||||
(*cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
|
(*cptr >= 'A' && *cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
|
||||||
(*cptr >= 'a' && *cptr - ('a' - 'A') == *kptr)) {
|
(*cptr >= 'a' && *cptr <= 'z' && *cptr - ('a' - 'A') == *kptr)) {
|
||||||
cptr++;
|
cptr++;
|
||||||
kptr++;
|
kptr++;
|
||||||
|
|
||||||
|
@ -8589,6 +8589,16 @@ DriverEntry(
|
||||||
&hwInitializationData.comm,
|
&hwInitializationData.comm,
|
||||||
(PVOID)(i | (alt ? 0x80000000 : 0)));
|
(PVOID)(i | (alt ? 0x80000000 : 0)));
|
||||||
KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
|
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) {
|
if (newStatus < statusToReturn) {
|
||||||
statusToReturn = newStatus;
|
statusToReturn = newStatus;
|
||||||
}
|
}
|
||||||
|
@ -9090,7 +9100,7 @@ AtapiRegCheckParameterValue(
|
||||||
|
|
||||||
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
|
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
|
||||||
paramPath.Buffer, parameters, NULL, NULL);
|
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);
|
ExFreePool(paramPath.Buffer);
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,11 @@ UniataChipDetectChannels(
|
||||||
deviceExtension->NumberChannels = 1;
|
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) {
|
switch(VendorID) {
|
||||||
case ATA_ACER_LABS_ID:
|
case ATA_ACER_LABS_ID:
|
||||||
switch(deviceExtension->DevID) {
|
switch(deviceExtension->DevID) {
|
||||||
|
@ -102,8 +107,8 @@ UniataChipDetectChannels(
|
||||||
case ATA_ATI_ID:
|
case ATA_ATI_ID:
|
||||||
KdPrint2((PRINT_PREFIX "ATI\n"));
|
KdPrint2((PRINT_PREFIX "ATI\n"));
|
||||||
switch(deviceExtension->DevID) {
|
switch(deviceExtension->DevID) {
|
||||||
case 0x438c1002:
|
case ATA_ATI_IXP600:
|
||||||
case 0x439c1002:
|
case ATA_ATI_IXP700:
|
||||||
/* IXP600 & IXP700 only have 1 PATA channel */
|
/* IXP600 & IXP700 only have 1 PATA channel */
|
||||||
if(BMList[deviceExtension->DevIndex].channel) {
|
if(BMList[deviceExtension->DevIndex].channel) {
|
||||||
KdPrint2((PRINT_PREFIX "New ATI no 2nd PATA chan\n"));
|
KdPrint2((PRINT_PREFIX "New ATI no 2nd PATA chan\n"));
|
||||||
|
@ -142,6 +147,12 @@ UniataChipDetectChannels(
|
||||||
deviceExtension->NumberChannels = 3;
|
deviceExtension->NumberChannels = 3;
|
||||||
KdPrint2((PRINT_PREFIX "VIA 3 chan\n"));
|
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;
|
break;
|
||||||
case ATA_ITE_ID:
|
case ATA_ITE_ID:
|
||||||
/* ITE ATA133 controller */
|
/* ITE ATA133 controller */
|
||||||
|
@ -981,32 +992,14 @@ for_ugly_chips:
|
||||||
IsPata = FALSE;
|
IsPata = FALSE;
|
||||||
if(ChipFlags & ICH5) {
|
if(ChipFlags & ICH5) {
|
||||||
if ((tmp8 & 0x04) == 0) {
|
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->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) {
|
} else if ((tmp8 & 0x02) == 0) {
|
||||||
//ch->flags |= ATA_SATA;
|
if(c != 0) {
|
||||||
//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 {
|
|
||||||
IsPata = TRUE;
|
IsPata = TRUE;
|
||||||
//chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
|
//chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
|
||||||
}
|
}
|
||||||
} else if ((tmp8 & 0x02) != 0) {
|
} else if ((tmp8 & 0x02) != 0) {
|
||||||
//ch->flags |= ATA_SATA;
|
if(c != 1) {
|
||||||
//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 {
|
|
||||||
IsPata = TRUE;
|
IsPata = TRUE;
|
||||||
//chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
|
//chan->ChannelCtrlFlags |= CTRFLAGS_PATA;
|
||||||
}
|
}
|
||||||
|
@ -1014,28 +1007,16 @@ for_ugly_chips:
|
||||||
} else
|
} else
|
||||||
if(ChipFlags & I6CH2) {
|
if(ChipFlags & I6CH2) {
|
||||||
chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
||||||
chan->lun[0]->SATA_lun_map = c ? 4 : 5;
|
|
||||||
chan->lun[1]->SATA_lun_map = 0;
|
|
||||||
} else {
|
} else {
|
||||||
switch(tmp8 & 0x03) {
|
switch(tmp8 & 0x03) {
|
||||||
case 0:
|
|
||||||
chan->lun[0]->SATA_lun_map = 0+c;
|
|
||||||
chan->lun[1]->SATA_lun_map = 2+c;
|
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
if(c==0) {
|
if(c!=0) {
|
||||||
chan->lun[0]->SATA_lun_map = 0;
|
|
||||||
chan->lun[1]->SATA_lun_map = 2;
|
|
||||||
} else {
|
|
||||||
// PATA
|
// PATA
|
||||||
IsPata = TRUE;
|
IsPata = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if(c==1) {
|
if(c!=1) {
|
||||||
chan->lun[0]->SATA_lun_map = 1;
|
|
||||||
chan->lun[1]->SATA_lun_map = 3;
|
|
||||||
} else {
|
|
||||||
// PATA
|
// PATA
|
||||||
IsPata = TRUE;
|
IsPata = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1045,9 +1026,11 @@ for_ugly_chips:
|
||||||
|
|
||||||
if(IsPata) {
|
if(IsPata) {
|
||||||
chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
|
chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA5);
|
||||||
|
KdPrint2((PRINT_PREFIX "PATA part\n"));
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if((ChipFlags & ICH5) && BaseMemAddress) {
|
if((ChipFlags & ICH5) && BaseMemAddress) {
|
||||||
|
KdPrint2((PRINT_PREFIX "ICH5 indexed\n"));
|
||||||
chan->RegTranslation[IDX_INDEXED_ADDR].Addr = BaseMemAddress + 0;
|
chan->RegTranslation[IDX_INDEXED_ADDR].Addr = BaseMemAddress + 0;
|
||||||
chan->RegTranslation[IDX_INDEXED_ADDR].MemIo = MemIo;
|
chan->RegTranslation[IDX_INDEXED_ADDR].MemIo = MemIo;
|
||||||
chan->RegTranslation[IDX_INDEXED_DATA].Addr = BaseMemAddress + 4;
|
chan->RegTranslation[IDX_INDEXED_DATA].Addr = BaseMemAddress + 4;
|
||||||
|
@ -1055,6 +1038,7 @@ for_ugly_chips:
|
||||||
}
|
}
|
||||||
if((ChipFlags & ICH5) || BaseMemAddress) {
|
if((ChipFlags & ICH5) || BaseMemAddress) {
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX "i indexed\n"));
|
||||||
// Rather interesting way of register access...
|
// Rather interesting way of register access...
|
||||||
ChipType = INTEL_IDX;
|
ChipType = INTEL_IDX;
|
||||||
deviceExtension->HwFlags &= ~CHIPTYPE_MASK;
|
deviceExtension->HwFlags &= ~CHIPTYPE_MASK;
|
||||||
|
@ -1085,6 +1069,10 @@ for_ugly_chips:
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ChipFlags & UNIATA_AHCI) {
|
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;
|
return UniataAhciInit(HwDeviceExtension) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1395,8 +1383,8 @@ UniAtaReadLunConfig(
|
||||||
c = channel - deviceExtension->Channel; // logical channel
|
c = channel - deviceExtension->Channel; // logical channel
|
||||||
|
|
||||||
chan = &deviceExtension->chan[c];
|
chan = &deviceExtension->chan[c];
|
||||||
ldev &= 0x01;
|
ldev &= (deviceExtension->NumberLuns-1);
|
||||||
LunExt = &(deviceExtension->lun[c*2+ldev]);
|
LunExt = &(deviceExtension->lun[c*deviceExtension->NumberLuns+ldev]);
|
||||||
|
|
||||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"ReadCacheEnable", 1);
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"ReadCacheEnable", 1);
|
||||||
LunExt->opt_ReadCacheEnable = tmp32 ? TRUE : FALSE;
|
LunExt->opt_ReadCacheEnable = tmp32 ? TRUE : FALSE;
|
||||||
|
@ -1441,6 +1429,7 @@ AtapiReadChipConfig(
|
||||||
PHW_CHANNEL chan;
|
PHW_CHANNEL chan;
|
||||||
ULONG tmp32;
|
ULONG tmp32;
|
||||||
ULONG c; // logical channel (for Compatible Mode controllers)
|
ULONG c; // logical channel (for Compatible Mode controllers)
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: devExt %#x\n", deviceExtension ));
|
KdPrint2((PRINT_PREFIX "AtapiReadChipConfig: devExt %#x\n", deviceExtension ));
|
||||||
ASSERT(deviceExtension);
|
ASSERT(deviceExtension);
|
||||||
|
@ -1504,8 +1493,9 @@ AtapiReadChipConfig(
|
||||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"ReorderEnable", TRUE);
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, c, DEVNUM_NOT_SPECIFIED, L"ReorderEnable", TRUE);
|
||||||
chan->UseReorder = tmp32 ? TRUE : FALSE;
|
chan->UseReorder = tmp32 ? TRUE : FALSE;
|
||||||
|
|
||||||
UniAtaReadLunConfig(deviceExtension, channel, 0);
|
for(i=0; i<deviceExtension->NumberLuns; i++) {
|
||||||
UniAtaReadLunConfig(deviceExtension, channel, 1);
|
UniAtaReadLunConfig(deviceExtension, channel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1656,25 +1646,104 @@ AtapiChipInit(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ATA_INTEL_ID: {
|
case ATA_INTEL_ID: {
|
||||||
|
BOOLEAN IsPata;
|
||||||
USHORT reg54;
|
USHORT reg54;
|
||||||
|
UCHAR tmp8;
|
||||||
if(ChipFlags & UNIATA_SATA) {
|
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;
|
break;
|
||||||
|
}
|
||||||
if(c == CHAN_NOT_SPECIFIED) {
|
if(c == CHAN_NOT_SPECIFIED) {
|
||||||
|
KdPrint2((PRINT_PREFIX "Base init\n"));
|
||||||
/* force all ports active "the legacy way" */
|
/* force all ports active "the legacy way" */
|
||||||
ChangePciConfig2(0x92, (a | 0x0f));
|
ChangePciConfig2(0x92, (a | 0x0f));
|
||||||
/* enable PCI interrupt */
|
/* enable PCI interrupt */
|
||||||
ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
|
ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
|
||||||
|
|
||||||
} else {
|
} 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) {
|
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];
|
chan = &deviceExtension->chan[c];
|
||||||
UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
|
UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
|
||||||
if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
|
if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
|
||||||
UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 1);
|
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_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]));
|
RtlCopyMemory(&chan->RegTranslation[IDX_IO2_o], &chan->RegTranslation[IDX_IO2], IDX_IO2_SZ*sizeof(chan->RegTranslation[0]));
|
||||||
} // end UniataInitSyncBaseIO()
|
} // 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()
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,11 @@ AtapiGetIoRange(
|
||||||
ScsiPortConvertUlongToPhysicalAddress(io_start);
|
ScsiPortConvertUlongToPhysicalAddress(io_start);
|
||||||
(*ConfigInfo->AccessRanges)[rid].RangeLength = length;
|
(*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 {
|
} else {
|
||||||
io_start = 0;
|
io_start = 0;
|
||||||
}
|
}
|
||||||
|
@ -252,6 +257,7 @@ UniataEnumBusMasterController__(
|
||||||
|
|
||||||
BOOLEAN found;
|
BOOLEAN found;
|
||||||
BOOLEAN known;
|
BOOLEAN known;
|
||||||
|
BOOLEAN NeedPciAltInit;
|
||||||
|
|
||||||
UCHAR IrqForCompat = 10;
|
UCHAR IrqForCompat = 10;
|
||||||
|
|
||||||
|
@ -269,6 +275,7 @@ UniataEnumBusMasterController__(
|
||||||
for(pass=0; pass<3; pass++) {
|
for(pass=0; pass<3; pass++) {
|
||||||
for(busNumber=0 ;busNumber<maxPciBus && !no_buses; busNumber++) {
|
for(busNumber=0 ;busNumber<maxPciBus && !no_buses; busNumber++) {
|
||||||
for(slotNumber=0; slotNumber<PCI_MAX_DEVICES && !no_buses; slotNumber++) {
|
for(slotNumber=0; slotNumber<PCI_MAX_DEVICES && !no_buses; slotNumber++) {
|
||||||
|
NeedPciAltInit = FALSE;
|
||||||
for(funcNumber=0; funcNumber<PCI_MAX_FUNCTION && !no_buses; funcNumber++) {
|
for(funcNumber=0; funcNumber<PCI_MAX_FUNCTION && !no_buses; funcNumber++) {
|
||||||
|
|
||||||
// KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
|
// KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
|
||||||
|
@ -288,11 +295,15 @@ UniataEnumBusMasterController__(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// no device in this slot
|
// no device in this slot
|
||||||
if(busDataRead == 2)
|
if(busDataRead == 2) {
|
||||||
|
NeedPciAltInit = TRUE;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH)
|
if(busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
|
||||||
|
NeedPciAltInit = TRUE;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
VendorID = pciData.VendorID;
|
VendorID = pciData.VendorID;
|
||||||
DeviceID = pciData.DeviceID;
|
DeviceID = pciData.DeviceID;
|
||||||
|
@ -304,6 +315,7 @@ UniataEnumBusMasterController__(
|
||||||
if(BaseClass != PCI_DEV_CLASS_STORAGE)
|
if(BaseClass != PCI_DEV_CLASS_STORAGE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
|
||||||
KdPrint2((PRINT_PREFIX "Storage Class\n"));
|
KdPrint2((PRINT_PREFIX "Storage Class\n"));
|
||||||
KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
||||||
// look for known chipsets
|
// look for known chipsets
|
||||||
|
@ -528,9 +540,10 @@ UniataEnumBusMasterController__(
|
||||||
newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0;
|
newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0;
|
||||||
newBMListPtr->busNumber = busNumber;
|
newBMListPtr->busNumber = busNumber;
|
||||||
|
|
||||||
|
newBMListPtr->NeedAltInit = NeedPciAltInit;
|
||||||
newBMListPtr->Known = known;
|
newBMListPtr->Known = known;
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "Add to BMList\n"));
|
KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit));
|
||||||
} else {
|
} else {
|
||||||
KdPrint2((PRINT_PREFIX "count: BMListLen++\n"));
|
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) {
|
if (!deviceExtension->lun) {
|
||||||
KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
|
KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
|
||||||
return FALSE;
|
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));
|
deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
|
||||||
if (!deviceExtension->chan) {
|
if (!deviceExtension->chan) {
|
||||||
|
@ -1025,7 +1038,8 @@ UniataFindBusMasterController(
|
||||||
deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
|
deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
|
||||||
deviceExtension->DevID = dev_id;
|
deviceExtension->DevID = dev_id;
|
||||||
deviceExtension->RevID = RevID;
|
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;
|
deviceExtension->DevIndex = i;
|
||||||
|
|
||||||
_snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
|
_snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
|
||||||
|
@ -1266,9 +1280,9 @@ UniataFindBusMasterController(
|
||||||
}
|
}
|
||||||
|
|
||||||
if(simplexOnly && MasterDev) {
|
if(simplexOnly && MasterDev) {
|
||||||
if(deviceExtension->NumberChannels < 2) {
|
if(deviceExtension->NumberChannels < IDE_DEFAULT_MAX_CHAN) {
|
||||||
KdPrint2((PRINT_PREFIX "set NumberChannels = 2\n"));
|
KdPrint2((PRINT_PREFIX "set NumberChannels = %d\n", IDE_DEFAULT_MAX_CHAN));
|
||||||
deviceExtension->NumberChannels = 2;
|
deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN;
|
||||||
if(BaseIoAddressBM_0) {
|
if(BaseIoAddressBM_0) {
|
||||||
UniataInitMapBM(deviceExtension,
|
UniataInitMapBM(deviceExtension,
|
||||||
BaseIoAddressBM_0,
|
BaseIoAddressBM_0,
|
||||||
|
@ -1289,7 +1303,7 @@ UniataFindBusMasterController(
|
||||||
KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0]));
|
KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0]));
|
||||||
}
|
}
|
||||||
// Indicate four devices can be attached to the adapter
|
// Indicate four devices can be attached to the adapter
|
||||||
ConfigInfo->MaximumNumberOfTargets = (UCHAR)(/*deviceExtension->NumberChannels **/ 2);
|
ConfigInfo->MaximumNumberOfTargets = (UCHAR)(deviceExtension->NumberLuns);
|
||||||
|
|
||||||
if (MasterDev) {
|
if (MasterDev) {
|
||||||
KdPrint2((PRINT_PREFIX "MasterDev (2)\n"));
|
KdPrint2((PRINT_PREFIX "MasterDev (2)\n"));
|
||||||
|
@ -1461,6 +1475,15 @@ UniataFindBusMasterController(
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
(*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeLength = 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;
|
IoBasePort1 = (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart;
|
||||||
|
@ -1860,7 +1883,8 @@ UniataFindFakeBusMasterController(
|
||||||
deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
|
deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
|
||||||
deviceExtension->DevID = dev_id;
|
deviceExtension->DevID = dev_id;
|
||||||
deviceExtension->RevID = RevID;
|
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;
|
deviceExtension->DevIndex = i;
|
||||||
|
|
||||||
_snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
|
_snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
|
||||||
|
@ -2291,6 +2315,7 @@ AtapiFindController(
|
||||||
KdPrint2((PRINT_PREFIX " assume max PIO4\n"));
|
KdPrint2((PRINT_PREFIX " assume max PIO4\n"));
|
||||||
deviceExtension->MaxTransferMode = ATA_PIO4;
|
deviceExtension->MaxTransferMode = ATA_PIO4;
|
||||||
deviceExtension->NumberChannels = 1;
|
deviceExtension->NumberChannels = 1;
|
||||||
|
deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
|
||||||
|
|
||||||
if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
|
if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
|
||||||
goto exit_error;
|
goto exit_error;
|
||||||
|
@ -2525,7 +2550,7 @@ not_found:
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigInfo->NumberOfBuses = 1;
|
ConfigInfo->NumberOfBuses = 1;
|
||||||
ConfigInfo->MaximumNumberOfTargets = 2;
|
ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN;
|
||||||
|
|
||||||
// Indicate maximum transfer length is 64k.
|
// Indicate maximum transfer length is 64k.
|
||||||
ConfigInfo->MaximumTransferLength = 0x10000;
|
ConfigInfo->MaximumTransferLength = 0x10000;
|
||||||
|
@ -2970,7 +2995,7 @@ FindDevices(
|
||||||
// Clear expecting interrupt flag and current SRB field.
|
// Clear expecting interrupt flag and current SRB field.
|
||||||
chan->ExpectingInterrupt = FALSE;
|
chan->ExpectingInterrupt = FALSE;
|
||||||
// chan->CurrentSrb = NULL;
|
// 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));
|
KdPrint2((PRINT_PREFIX " max_ldev %d\n", max_ldev));
|
||||||
|
|
||||||
// Search for devices.
|
// Search for devices.
|
||||||
|
|
|
@ -380,32 +380,64 @@ UniataAhciInit(
|
||||||
ULONG BaseMemAddress;
|
ULONG BaseMemAddress;
|
||||||
ULONG PI;
|
ULONG PI;
|
||||||
ULONG CAP;
|
ULONG CAP;
|
||||||
|
ULONG GHC;
|
||||||
BOOLEAN MemIo;
|
BOOLEAN MemIo;
|
||||||
ULONGLONG base;
|
ULONGLONG base;
|
||||||
|
|
||||||
/* reset AHCI controller */
|
/* reset AHCI controller */
|
||||||
AtapiWritePortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC,
|
GHC = AtapiReadPortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC);
|
||||||
AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) | AHCI_GHC_HR);
|
KdPrint2((PRINT_PREFIX " reset AHCI controller, GHC %x\n", GHC));
|
||||||
AtapiStallExecution(1000000);
|
AtapiWritePortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
|
||||||
if(AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) & AHCI_GHC_HR) {
|
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"));
|
KdPrint2((PRINT_PREFIX " AHCI reset failed\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable AHCI mode */
|
/* enable AHCI mode */
|
||||||
AtapiWritePortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC,
|
GHC = AtapiReadPortEx4(NULL, (ULONG_PTR)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC);
|
||||||
AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) | AHCI_GHC_AE);
|
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);
|
CAP = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_CAP);
|
||||||
PI = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_PI);
|
PI = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_PI);
|
||||||
/* get the number of HW channels */
|
KdPrint2((PRINT_PREFIX " AHCI CAP %x\n", CAP));
|
||||||
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) {
|
if(CAP & AHCI_CAP_S64A) {
|
||||||
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
|
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
|
||||||
deviceExtension->Host64 = TRUE;
|
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 */
|
/* clear interrupts */
|
||||||
AtapiWritePortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_IS,
|
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);
|
AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_GHC) | AHCI_GHC_IE);
|
||||||
|
|
||||||
version = AtapiReadPortEx4(NULL, (ULONG_PTR)(&deviceExtension->BaseIoAHCI_0), IDX_AHCI_VS);
|
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",
|
KdPrint2((PRINT_PREFIX " AHCI version %x.%02x controller with %d ports (mask %x) detected\n",
|
||||||
(version >> 24) & 0xff, (version >> 16) & 0xff,
|
((version >> 20) & 0xf0) + ((version >> 16) & 0x0f),
|
||||||
(version >> 8) & 0xff, version & 0xff, deviceExtension->NumberChannels, PI));
|
((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_SATA;
|
||||||
deviceExtension->HwFlags |= UNIATA_AHCI;
|
deviceExtension->HwFlags |= UNIATA_AHCI;
|
||||||
|
|
|
@ -43,9 +43,9 @@ extern "C" {
|
||||||
#endif //__cplusplus
|
#endif //__cplusplus
|
||||||
|
|
||||||
#define AHCI_MAX_PORT 32
|
#define AHCI_MAX_PORT 32
|
||||||
#define IDE_MAX_CHAN 8
|
#define IDE_MAX_CHAN 16
|
||||||
// Thanks to SATA Port Multipliers:
|
// 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 IDE_MAX_LUN (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN)
|
||||||
|
|
||||||
#define MAX_QUEUE_STAT 8
|
#define MAX_QUEUE_STAT 8
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#define UNIATA_VER_STR "40a1"
|
#define UNIATA_VER_STR "40a5"
|
||||||
#define UNIATA_VER_DOT 0.40.1.1
|
#define UNIATA_VER_DOT 0.40.1.5
|
||||||
#define UNIATA_VER_DOT_COMMA 0,40,1,1
|
#define UNIATA_VER_DOT_COMMA 0,40,1,5
|
||||||
#define UNIATA_VER_DOT_STR "0.40.1.1"
|
#define UNIATA_VER_DOT_STR "0.40.1.5"
|
||||||
#define UNIATA_VER_YEAR 2010
|
#define UNIATA_VER_YEAR 2010
|
||||||
#define UNIATA_VER_YEAR_STR "2010"
|
#define UNIATA_VER_YEAR_STR "2010"
|
||||||
|
|
Loading…
Reference in a new issue