Author: akhaldi Date: Mon Sep 14 10:24:48 2015 New Revision: 69224
URL: http://svn.reactos.org/svn/reactos?rev=69224&view=rev Log: [UNIATA] Sync to 0.45h1. CORE-10185
Modified: trunk/reactos/drivers/storage/ide/uniata/atapi.h trunk/reactos/drivers/storage/ide/uniata/bm_devs.h trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp trunk/reactos/drivers/storage/ide/uniata/id_dma.cpp trunk/reactos/drivers/storage/ide/uniata/id_init.cpp trunk/reactos/drivers/storage/ide/uniata/id_probe.cpp trunk/reactos/drivers/storage/ide/uniata/id_sata.cpp trunk/reactos/drivers/storage/ide/uniata/uniata_ver.h
Modified: trunk/reactos/drivers/storage/ide/uniata/atapi.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/atapi.h [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/atapi.h [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -437,6 +437,7 @@ #define IDE_DRIVE_2 0x10 #define IDE_DRIVE_SELECT_1 (IDE_DRIVE_SELECT | IDE_DRIVE_1) #define IDE_DRIVE_SELECT_2 (IDE_DRIVE_SELECT | IDE_DRIVE_2) +#define IDE_DRIVE_MASK (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)
#define IDE_USE_LBA 0x40
Modified: trunk/reactos/drivers/storage/ide/uniata/bm_devs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/bm_devs.h [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/bm_devs.h [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -696,6 +696,11 @@ #define VIAPRQ 0x8000 #define VIASATA 0x10000
+#define CYRIX_OLD 0 +#define CYRIX_3x 1 +#define CYRIX_NEW 2 +#define CYRIX_35 3 + #define ITE_33 0 #define ITE_133 1 #define ITE_133_NEW 2 @@ -734,6 +739,7 @@ PCI_DEV_HW_SPEC_BM( 7411, 1022, 0x00, ATA_UDMA5, "AMD 766" , 0 | AMDBUG ), PCI_DEV_HW_SPEC_BM( 7441, 1022, 0x00, ATA_UDMA5, "AMD 768" , 0 ), PCI_DEV_HW_SPEC_BM( 7469, 1022, 0x00, ATA_UDMA6, "AMD 8111" , 0 ), + PCI_DEV_HW_SPEC_BM( 208F, 1022, 0x00, ATA_UDMA4, "AMD CS5535" , CYRIX_35 ), PCI_DEV_HW_SPEC_BM( 209a, 1022, 0x00, ATA_UDMA5, "AMD CS5536" , 0 ),
PCI_DEV_HW_SPEC_BM( 4349, 1002, 0x00, ATA_UDMA5, "ATI IXP200" , 0 ), @@ -1041,6 +1047,7 @@ PCI_DEV_HW_SPEC_BM( 0d8f, 10de, 0x00, ATA_SA300, "nVidia nForce MCP89 AB", UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 0502, 100b, 0x00, ATA_UDMA2, "National Geode SC1100", 0 ), + PCI_DEV_HW_SPEC_BM( 002d, 100b, 0x00, ATA_UDMA4, "National Geode CS5535", CYRIX_35 ),
PCI_DEV_HW_SPEC_BM( 4d33, 105a, 0x00, ATA_UDMA2, "Promise PDC20246" , PROLD | 0x00 ), PCI_DEV_HW_SPEC_BM( 4d38, 105a, 0x00, ATA_UDMA4, "Promise PDC20262" , PRNEW | 0x00 ), @@ -1204,7 +1211,9 @@ */ PCI_DEV_HW_SPEC_BM( 0001, 16ca, 0x00, ATA_WDMA2, "Cenatek Rocket Drive",0 ),
- PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530" , 0 ), + PCI_DEV_HW_SPEC_BM( 0000, 1078, 0x00, ATA_WDMA2, "Cyrix 5510" , CYRIX_OLD ), + PCI_DEV_HW_SPEC_BM( 0002, 1078, 0x00, ATA_WDMA2, "Cyrix 5520" , CYRIX_OLD ), + PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530" , CYRIX_3x ),
PCI_DEV_HW_SPEC_BM( 1000, 1042, 0x00, ATA_PIO4, "RZ 100x" , 0 ), PCI_DEV_HW_SPEC_BM( 1001, 1042, 0x00, ATA_PIO4, "RZ 100x" , 0 ),
Modified: trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -1,6 +1,6 @@ /*++
-Copyright (c) 2002-2014 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
Module Name: id_ata.cpp @@ -498,6 +498,7 @@ if (statusByte & IDE_STATUS_DRQ) { // Suck out any remaining bytes and throw away. AtapiReadPort2(chan, IDX_IO1_i_Data); + UniataNanoSleep(PIO0_TIMING); } else { break; } @@ -507,6 +508,50 @@ } return statusByte; } // AtapiSuckPort2() + +ULONG +DDKFASTAPI +AtapiSuckPortBuffer2( + IN PHW_CHANNEL chan, + IN PUSHORT Buffer, + IN ULONG Count + ) +{ + UCHAR statusByte; + ULONG i; + USHORT data; + BOOLEAN retry = FALSE; + + // Assume, proper drive is already seleted + WaitOnBusyLong(chan); + for (i = 0; i < Count; i++) { + + GetStatus(chan, statusByte); + if (statusByte & IDE_STATUS_DRQ) { + // Suck out any remaining bytes and throw away. + data = AtapiReadPort2(chan, IDX_IO1_i_Data); + (*Buffer) = data; + Count--; + Buffer++; + UniataNanoSleep(PIO0_TIMING); + retry = FALSE; + } else { + if(i<Count && !retry) { + KdPrint2((PRINT_PREFIX " wait...\n")); + WaitForDrq(chan); + retry = TRUE; + } + break; + } + } + if(i) { + KdPrint2((PRINT_PREFIX "AtapiSuckPortBuffer2: %#x words\n", i )); + if(i==Count) { + AtapiSuckPort2(chan); + } + } + return i; +} // AtapiSuckPortBuffer2()
UCHAR DDKFASTAPI @@ -1253,7 +1298,7 @@
#endif //UNIATA_CORE
-#if DBG +#ifdef _DEBUG VOID NTAPI UniataDumpATARegs( @@ -1383,7 +1428,7 @@
if(use_ahci) { statusByte = WaitOnBusyLong(chan); -#if DBG +#ifdef _DEBUG if(!chan->AhciInternalAtaReq) { KdPrint2((PRINT_PREFIX "!AhciInternalAtaReq\n")); } @@ -1594,11 +1639,24 @@ if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
KdPrint2((PRINT_PREFIX " use 16bit IO\n")); - +#ifdef _DEBUG + if(atapiDev) { + j = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask); + KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j)); + + j = + AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow); + + j |= + (USHORT)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8; + KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j)); + + } +#endif //DBG // ATI/SII chipsets with memory-mapped IO hangs when // I call ReadBuffer(), probably due to PCI burst/prefetch enabled // Unfortunately, I don't know yet how to workaround it except - // spacifying manual delay in the way you see below. + // specifying manual delay in the way you see below. ReadBuffer(chan, (PUSHORT)&deviceExtension->FullIdentifyData, 256, PIO0_TIMING);
// Work around for some IDE and one model Atapi that will present more than @@ -2003,10 +2061,12 @@ LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_CD; LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_CD; statusByte = WaitForDrq(chan); + } else { KdPrint2((PRINT_PREFIX "IssueIdentify: ATAPI drive type %#x.\n", LunExt->IdentifyData.DeviceType)); } + KdPrint2((PRINT_PREFIX "IssueIdentify: AtapiCmdSize %#x\n", deviceExtension->FullIdentifyData.AtapiCmdSize)); } else { KdPrint2((PRINT_PREFIX "IssueIdentify: hard drive.\n")); } @@ -2142,7 +2202,7 @@ //ULONG RevID = deviceExtension->RevID; ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK; //UCHAR tmp8; - UCHAR tmp16; + USHORT tmp16;
KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber)); KdPrint2((PRINT_PREFIX "simplexOnly %d\n", deviceExtension->simplexOnly)); @@ -2171,6 +2231,19 @@ PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension);
KdPrint2((PRINT_PREFIX "AtapiResetController: pending SRB %#x, chan %#x\n", CurSrb, chan)); + if(CurSrb->Cdb[0] == SCSIOP_MECHANISM_STATUS) { + PHW_LU_EXTENSION LunExt; + KdPrint2((PRINT_PREFIX " was MechStatus\n")); + + i = GET_CDEV(CurSrb); + KdPrint2((PRINT_PREFIX " Lun %x\n", i)); + LunExt = chan->lun[i]; + + if(!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)) { + LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED; + KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n")); + } + } // Check and see if we are processing an internal srb if (AtaReq->OriginalSrb) { KdPrint2((PRINT_PREFIX " restore original SRB %#x\n", AtaReq->OriginalSrb)); @@ -2324,9 +2397,40 @@ break; } case ATA_SIS_ID: case ATA_NVIDIA_ID: { + ULONG offs; + ULONG Channel = deviceExtension->Channel + j; KdPrint2((PRINT_PREFIX " SIS/nVidia\n")); - if(!(ChipFlags & UNIATA_SATA)) + if(!(ChipFlags & UNIATA_SATA)) { goto default_reset; + } + offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010; + + KdPrint2((PRINT_PREFIX " disable Phy intr, offs %#x, c %u\n", offs, Channel)); + /* disable device and PHY state change interrupts */ + if(ChipFlags & NVQ) { + KdPrint2((PRINT_PREFIX " NVQ, 32bits reg\n")); + AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, + AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) & ((~(ULONG)0x0000000d) << (!Channel*16)) ); + } else { + AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, + AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) & ((~(UCHAR)0x0d) << (!Channel*4)) ); + } + tmp16 = UniataSataPhyEnable(HwDeviceExtension, j, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE); + + KdPrint2((PRINT_PREFIX " enable Phy intr, offs %#x\n", offs)); + /* enable device and PHY state change interrupts */ + if(ChipFlags & NVQ) { + AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, + AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) | (((ULONG)0x0000000d) << (!Channel*16)) ); + } else { + AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, + AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) | (((UCHAR)0x0d) << (!Channel*4)) ); + } + + KdPrint2((PRINT_PREFIX " dev status %#x\n", tmp16)); + if(tmp16 != IDE_STATUS_WRONG) { + goto default_reset; + } break; } case ATA_SILICON_IMAGE_ID: { ULONG offset; @@ -2458,6 +2562,22 @@
GetStatus(chan, statusByte);
+ if(statusByte != IDE_STATUS_SUCCESS) { + ULONG k; + k = UniataAnybodyHome(deviceExtension, j, i); + if(k == ATA_AT_HOME_HDD) { + // device reset in progress, perform additional wait + KdPrint2((PRINT_PREFIX " long reset, wait up to 4.5 s\n")); + k = 30 * 1000; + while ((AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) && + k--) + { + AtapiStallExecution(150); + } + KdPrint2((PRINT_PREFIX " exit after %u loops\n", k)); + GetStatus(chan, statusByte); + } + } if(statusByte == IDE_STATUS_SUCCESS) {
IssueIdentify(HwDeviceExtension, @@ -4261,7 +4381,7 @@ pr_status = AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs); AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0f << shift)); } - KdPrint2((PRINT_PREFIX " pr_status %x\n", pr_status)); + KdPrint2((PRINT_PREFIX " pr_status %x, shift %x\n", pr_status, shift));
/* check for and handle connect events */ if(((pr_status & (0x0cUL << shift)) == (0x04UL << shift)) ) { @@ -5094,6 +5214,15 @@ interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask); KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
+ if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { + if(deviceExtension->HwFlags & UNIATA_AHCI) { + // Do nothing here + } else + if(deviceExtension->HwFlags & UNIATA_SATA) { + UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0); + } + } + if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) && ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) { if(AtaReq->retry < MAX_RETRIES) { @@ -5356,24 +5485,24 @@ // Ensure that this is a write command. if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
- KdPrint2((PRINT_PREFIX - "AtapiInterrupt: Write interrupt\n")); - - statusByte = WaitOnBusy(chan); - - if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) { - - WriteBuffer(chan, - AtaReq->DataBuffer, - wordCount, - UniataGetPioTiming(LunExt)); - } else { - - WriteBuffer2(chan, - (PULONG)(AtaReq->DataBuffer), - wordCount / 2, - UniataGetPioTiming(LunExt)); - } + KdPrint2((PRINT_PREFIX + "AtapiInterrupt: Write interrupt\n")); + + statusByte = WaitOnBusy(chan); + + if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) { + + WriteBuffer(chan, + AtaReq->DataBuffer, + wordCount, + UniataGetPioTiming(LunExt)); + } else { + + WriteBuffer2(chan, + (PULONG)(AtaReq->DataBuffer), + wordCount / 2, + UniataGetPioTiming(LunExt)); + } } else {
KdPrint3((PRINT_PREFIX @@ -5381,8 +5510,43 @@ interruptReason, srb));
+ if(!wordCount && atapiDev && + !(statusByte & (IDE_STATUS_ERROR | IDE_STATUS_BUSY)) && + (statusByte & IDE_STATUS_DRQ)) { + // this can be late Packet interrupt after packet sending + KdPrint2((PRINT_PREFIX " unreliable wordCount ?\n")); + + wordCount = AtapiSuckPortBuffer2(chan, + AtaReq->DataBuffer, + AtaReq->WordsLeft); + KdPrint2((PRINT_PREFIX " transferred %#x\n", wordCount)); + GetBaseStatus(chan, statusByte); + KdPrint2((PRINT_PREFIX " status %#x, statusByte\n")); + if(wordCount) { + interruptReason = ATAPI_IR_IO_toHost; +#ifdef _DEBUG + UniataDumpATARegs(chan); +#endif + } + if(wordCount && AtaReq->WordsLeft) { + goto continue_atapi_pio_read; + } + } // Fail this request. status = SRB_STATUS_ERROR; + if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) { + // some devices feel bad after incorrect commands and may need reset + KdPrint2((PRINT_PREFIX + "AtapiInterrupt: Try ATAPI reset\n")); + + AtapiDisableInterrupts(deviceExtension, lChannel); + AtapiSoftReset(chan, DeviceNumber); + AtapiEnableInterrupts(deviceExtension, lChannel); + status = SRB_STATUS_BUS_RESET; + AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; + +// goto IntrPrepareResetController; + } goto CompleteRequest; } // Advance data buffer pointer and bytes left. @@ -5516,7 +5680,7 @@ status = SRB_STATUS_ERROR; goto CompleteRequest; } - +continue_atapi_pio_read: // Advance data buffer pointer and bytes left. AtaReq->DataBuffer += wordCount; AtaReq->WordsLeft -= wordCount; @@ -7554,7 +7718,13 @@ CHECK_INTR_IDLE); AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
+ // clear interrupt GetBaseStatus(chan, statusByte); + +#ifdef _DEBUG + statusByte = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", statusByte)); +#endif //DBG
if(g_opt_AtapiSendDisableIntr) { AtapiEnableInterrupts(deviceExtension, lChannel); @@ -7865,7 +8035,7 @@ } else { RtlZeroMemory(modeData, sizeof(MODE_POWER_CONDITION_PAGE)); modeData->PageCode = MODE_PAGE_POWER_CONDITION; - modeData->PageLength = sizeof(MODE_POWER_CONDITION_PAGE)-sizeof(MODE_PARAMETER_HEADER); + modeData->PageLength = sizeof(MODE_PAGE_POWER_CONDITION)-sizeof(MODE_PARAMETER_HEADER); modeData->Byte3.Fields.Idle = LunExt->PowerState <= StartStop_Power_Idle; modeData->Byte3.Fields.Standby = LunExt->PowerState == StartStop_Power_Standby; Srb->DataTransferLength = sizeof(MODE_POWER_CONDITION_PAGE); @@ -10038,7 +10208,7 @@ return status; } #endif // USE_REACTOS_DDK - KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, KeNumberProcessors)); + KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, *KeNumberProcessors));
KeQuerySystemTime(&t0); do { @@ -10145,7 +10315,7 @@ g_opt_WaitDrqDelay = 100; g_opt_WaitBusyLongCount = 20000; g_opt_MaxIsrWait = 200; - g_opt_AtapiSendDisableIntr = 0; + g_opt_AtapiSendDisableIntr = FALSE; g_opt_AtapiDmaRawRead = FALSE; break; } @@ -10165,8 +10335,8 @@ g_opt_WaitDrqDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitDrqDelay", g_opt_WaitDrqDelay); // 10 vs 100 g_opt_WaitBusyLongCount = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongCount", g_opt_WaitBusyLongCount); // 2000 vs 20000 g_opt_WaitBusyLongDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongDelay", g_opt_WaitBusyLongDelay); // 250 vs 250 - g_opt_AtapiSendDisableIntr = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiSendDisableIntr", g_opt_AtapiSendDisableIntr); // 1 vs 0 - g_opt_AtapiDmaRawRead = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead", g_opt_AtapiDmaRawRead); // 1 vs 0 + g_opt_AtapiSendDisableIntr = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiSendDisableIntr", g_opt_AtapiSendDisableIntr) ? TRUE : FALSE; // 1 vs 0 + g_opt_AtapiDmaRawRead = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead", g_opt_AtapiDmaRawRead) ? TRUE : FALSE; // 1 vs 0 g_opt_MaxIsrWait = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxIsrWait", g_opt_MaxIsrWait); // 40 vs xxx }
Modified: trunk/reactos/drivers/storage/ide/uniata/id_dma.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/id_dma.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/id_dma.cpp [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -1013,6 +1013,7 @@ /****************/
KdPrint2((PRINT_PREFIX "SATA Generic\n")); + if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || ((udmamode >= 0) && (chan->MaxTransferMode >= ATA_SA150))) { /* some drives report UDMA6, some UDMA5 */ /* ATAPI may not have SataCapabilities set in IDENTIFY DATA */ @@ -1235,29 +1236,85 @@ /*********/ /* Cyrix */ /*********/ - ULONG cyr_piotiming[] = - { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 }; - ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 }; - ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 }; - ULONG mode_reg = 0x24+(dev << 3); - +dma_cs55xx: if(apiomode >= 4) apiomode = 4; - for(i=udmamode; i>=0; i--) { - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { - AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]); - return; - } - } - for(i=wdmamode; i>=0; i--) { - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { - AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]); - return; - } - } - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { - AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]); - return; + + if(ChipType == CYRIX_3x) { + ULONG cyr_piotiming[] = + { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 }; + ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 }; + ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 }; + ULONG mode_reg = 0x24+(dev << 3); + + for(i=udmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { + AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]); + return; + } + } + for(i=wdmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { + AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]); + return; + } + } + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { + AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]); + return; + } + } else + if(ChipType == CYRIX_OLD) { + UCHAR cyr_piotiming_old[] = + { 11, 6, 3, 2, 1 }; + UCHAR timing; + + for(i=wdmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { + return; + } + } + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { + timing = (6-apiomode) | (cyr_piotiming_old[i]); + /* Channel command timing */ + SetPciConfig1(0x62+Channel, timing); + /* Read command timing */ + SetPciConfig1(0x64+Channel*4+dev, timing); + /* Write command timing */ + SetPciConfig1(0x66+Channel*4+dev, timing); + return; + } + } else + if(ChipType == CYRIX_35) { +/* + USHORT c35_pio_timings[5] = { + 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 + }; + USHORT c35_pio_cmd_timings[5] = { + 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 + }; + ULONG c35_udma_timings[5] = { + 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 + }; + ULONG c35_mwdma_timings[3] = { + 0x7F0FFFF3, 0x7F035352, 0x7F024241 + }; + ULONG mode_reg = 0x24+(dev << 3); +*/ + /* No MSR support yet, do not touch any regs */ + for(i=udmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { + return; + } + } + for(i=wdmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { + return; + } + } + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { + return; + } } return;
@@ -1266,33 +1323,37 @@ /************/ /* National */ /************/ - ULONG nat_piotiming[] = - { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010, - 0x00803020, 0x20102010, 0x00100010, - 0x00100010, 0x00100010, 0x00100010 }; - ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 }; - ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 }; - - if(apiomode >= 4) - apiomode = 4; - for(i=udmamode; i>=0; i--) { - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { - SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]); - SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]); - return; - } - } - for(i=wdmamode; i>=0; i--) { - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { - SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]); - SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]); - return; - } - } - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { - ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000); - SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]); - return; + if(!ChipType) { + ULONG nat_piotiming[] = + { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010, + 0x00803020, 0x20102010, 0x00100010, + 0x00100010, 0x00100010, 0x00100010 }; + ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 }; + ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 }; + + if(apiomode >= 4) + apiomode = 4; + for(i=udmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { + SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]); + SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]); + return; + } + } + for(i=wdmamode; i>=0; i--) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { + SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]); + SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]); + return; + } + } + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) { + ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000); + SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]); + return; + } + } else { + goto dma_cs55xx; } /* Use GENERIC PIO */ break; }
Modified: trunk/reactos/drivers/storage/ide/uniata/id_init.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/id_init.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/id_init.cpp [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -286,6 +286,21 @@ } deviceExtension->NumberChannels = 1; KdPrint2((PRINT_PREFIX "New JMicron PATA 1 chan\n")); + } + break; + case ATA_CYRIX_ID: + if(ChipType == CYRIX_OLD) { + UCHAR tmp8; + ULONG slotNumber; + slotNumber = deviceExtension->slotNumber; + KdPrint2((PRINT_PREFIX "Cyrix slot %#x\n", slotNumber)); + GetPciConfig1(0x60, tmp8); + if(tmp8 & (1 << BMList[deviceExtension->DevIndex].channel)) { + KdPrint2((PRINT_PREFIX "Old Cyrix chan %d ok\n", BMList[deviceExtension->DevIndex].channel)); + } else { + KdPrint2((PRINT_PREFIX "Old Cyrix no chan %d\n", BMList[deviceExtension->DevIndex].channel)); + return FALSE; + } } break; } // end switch(VendorID) @@ -2094,6 +2109,8 @@ KdPrint2((PRINT_PREFIX "Intel SATA\n")); if(ChipFlags & UNIATA_AHCI) { KdPrint2((PRINT_PREFIX "Do nothing for AHCI\n")); + /* enable PCI interrupt */ + ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400)); break; } if(c == CHAN_NOT_SPECIFIED) { @@ -2643,6 +2660,19 @@ if(ChipType == ITE_133_NEW) { } break; + case ATA_CYRIX_ID: + KdPrint2((PRINT_PREFIX "Cyrix\n")); + if(ChipType == CYRIX_OLD) { + if(c == CHAN_NOT_SPECIFIED) { + GetPciConfig1(0x60, tmp8); + if(!(tmp8 & 0x40)) { + KdPrint2((PRINT_PREFIX "Enable DMA\n")); + tmp8 |= 0x40; + SetPciConfig1(0x60, tmp8); + } + } + } + break; default: if(c != CHAN_NOT_SPECIFIED) { // We don't know how to check for 80-pin cable on unknown controllers.
Modified: trunk/reactos/drivers/storage/ide/uniata/id_probe.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/id_probe.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/id_probe.cpp [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -1,6 +1,6 @@ /*++
-Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
Module Name: id_probe.cpp @@ -53,6 +53,10 @@ ULONG MCACount = 0;
BOOLEAN FirstMasterOk = FALSE; +// This is our own resource check, +// ReactOS allows to allocate same I/O range for both PCI and ISA controllers +BOOLEAN AtdiskPrimaryClaimed = FALSE; +BOOLEAN AtdiskSecondaryClaimed = FALSE;
#ifndef UNIATA_CORE
@@ -1638,7 +1642,7 @@ chan->RegTranslation[IDX_SATA_IO].MemIo ? "mem" : "io"));
if(!(deviceExtension->HwFlags & UNIATA_AHCI)) { -#if DBG +#ifdef _DEBUG UniataDumpATARegs(chan); #endif
@@ -1721,6 +1725,7 @@ KdPrint2((PRINT_PREFIX "claim Compatible controller\n")); if (channel == 0) { KdPrint2((PRINT_PREFIX "claim Primary\n")); + AtdiskPrimaryClaimed = ConfigInfo->AtdiskPrimaryClaimed = TRUE; chan->PrimaryAddress = TRUE;
@@ -1729,9 +1734,23 @@ } else if (channel == 1) { KdPrint2((PRINT_PREFIX "claim Secondary\n")); + AtdiskSecondaryClaimed = ConfigInfo->AtdiskSecondaryClaimed = TRUE;
FirstMasterOk = TRUE; + } + } else { + if(chan->RegTranslation[IDX_IO1].Addr == IO_WD1 && + !chan->RegTranslation[IDX_IO1].MemIo) { + KdPrint2((PRINT_PREFIX "claim Primary (PCI over ISA range)\n")); + AtdiskPrimaryClaimed = + ConfigInfo->AtdiskPrimaryClaimed = TRUE; + } + if(chan->RegTranslation[IDX_IO1].Addr == IO_WD2 && + !chan->RegTranslation[IDX_IO1].MemIo) { + KdPrint2((PRINT_PREFIX "claim Secondary (PCI over ISA range)\n")); + AtdiskSecondaryClaimed = + ConfigInfo->AtdiskSecondaryClaimed = TRUE; } }
@@ -2250,12 +2269,12 @@ } // check if Primary/Secondary Master IDE claimed if((ioSpace == (PUCHAR)IO_WD1) && - (ConfigInfo->AtdiskPrimaryClaimed)) { + (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) { KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskPrimaryClaimed\n")); goto not_found; } else if((ioSpace == (PUCHAR)IO_WD2) && - (ConfigInfo->AtdiskSecondaryClaimed)) { + (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) { KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskSecondaryClaimed\n")); goto not_found; } @@ -2287,7 +2306,7 @@ UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); UniataInitMapBM(deviceExtension, 0, FALSE);
-#if DBG +#ifdef _DEBUG UniataDumpATARegs(chan); #endif
@@ -2697,6 +2716,7 @@ UCHAR statusByte; ULONG RetVal=0; ULONG waitCount = 10000; + ULONG at_home = 0;
KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n", deviceNumber)); @@ -2705,7 +2725,7 @@ return 0; } if(deviceExtension->HwFlags & UNIATA_AHCI) { - if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { + if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) { return 0; } } @@ -2713,6 +2733,20 @@
if(ResetDev) { LunExt->PowerState = 0; + } + + if((deviceExtension->HwFlags & UNIATA_SATA) && + !UniataIsSATARangeAvailable(deviceExtension, lChannel) && + deviceNumber) { + KdPrint2((PRINT_PREFIX " SATA w/o i/o registers, check slave presence\n")); + SelectDrive(chan, deviceNumber & 0x01); + statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect); + KdPrint2((PRINT_PREFIX " DriveSelect: %#x\n", statusByte)); + if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) { + KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n")); + UniataForgetDevice(LunExt); + return 0; + } }
if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) { @@ -2729,7 +2763,7 @@ // Reset device AtapiSoftReset(chan, deviceNumber);
- if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { + if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) { //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n")); return 0; } @@ -2787,7 +2821,7 @@ // Select the device. SelectDrive(chan, deviceNumber);
- if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { + if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) { //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n")); return 0; } @@ -2842,7 +2876,7 @@ // ATAPI signature found. // Issue the ATAPI identify command if this // is not for the crash dump utility. - +try_atapi: if (!deviceExtension->DriverMustPoll) {
// Issue ATAPI packet identify command. @@ -2872,7 +2906,7 @@ }
} else { - +forget_device: // Indicate no working device. KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n", deviceNumber)); @@ -2906,6 +2940,16 @@ RetVal = DFLAGS_DEVICE_PRESENT; LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT; LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; + } else { + // This can be ATAPI on broken hardware + GetBaseStatus(chan, statusByte); + if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { + KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n")); + goto forget_device; + } + KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n", + deviceNumber, statusByte)); + goto try_atapi; } GetBaseStatus(chan, statusByte); }
Modified: trunk/reactos/drivers/storage/ide/uniata/id_sata.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/id_sata.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/id_sata.cpp [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -728,12 +728,20 @@ }
/* re-enable AHCI mode */ + /* Linux: Some controllers need AHCI_EN to be written multiple times. + * Try a few times before giving up. + */ GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC); - if(!(GHC & AHCI_GHC_AE)) { - KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC)); - UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC, - GHC | AHCI_GHC_AE); - GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC); + for(i=0; i<5; i++) { + if(!(GHC & AHCI_GHC_AE)) { + KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC)); + UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC, + GHC | AHCI_GHC_AE); + AtapiStallExecution(1000); + GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC); + } else { + break; + } } KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC)); if(!(GHC & AHCI_GHC_AE)) { @@ -1980,6 +1988,7 @@ CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); KdPrint2((" CMD %#x\n", CMD)); UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD | ATA_AHCI_P_CMD_FRE); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
return; } // end UniataAhciStartFR() @@ -2039,6 +2048,7 @@ CMD | ATA_AHCI_P_CMD_ST | ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0)); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
return; } // end UniataAhciStart() @@ -2187,15 +2197,24 @@ if(CMD0 != CMD) { KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length)); UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */ }
/* issue command to controller */ //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag); + KdPrint2((" Set CI\n")); UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 0x01 << tag); chan->AhciPrevCI |= 0x01 << tag;
+ KdPrint2((" Send CMD START\n")); + UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, + CMD | + ATA_AHCI_P_CMD_ST | + ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0)); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */ + if(!ATAPI_DEVICE(chan, DeviceNumber)) { - // TODO: check if we send ATA_RESET and wait for ready of so. + // TODO: check if we send ATAPI_RESET and wait for ready of so. if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) { ULONG TFD; ULONG i; @@ -2365,6 +2384,7 @@ (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) | (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 )) ); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
#ifdef DBG //UniataDumpAhciPortRegs(chan); @@ -2399,6 +2419,7 @@ UniataAhciStop(chan); UniataAhciStopFR(chan); UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, 0); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
/* Allow everything including partial and slumber modes. */ UniataSataWritePort4(chan, IDX_SATA_SControl, 0, 0);
Modified: trunk/reactos/drivers/storage/ide/uniata/uniata_ver.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/... ============================================================================== --- trunk/reactos/drivers/storage/ide/uniata/uniata_ver.h [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/ide/uniata/uniata_ver.h [iso-8859-1] Mon Sep 14 10:24:48 2015 @@ -1,10 +1,10 @@ -#define UNIATA_VER_STR "45e" -#define UNIATA_VER_DOT 0.45.5.0 +#define UNIATA_VER_STR "45h1" +#define UNIATA_VER_DOT 0.45.8.1 #define UNIATA_VER_MJ 0 #define UNIATA_VER_MN 45 -#define UNIATA_VER_SUB_MJ 5 -#define UNIATA_VER_SUB_MN 0 -#define UNIATA_VER_DOT_COMMA 0,45,5,0 -#define UNIATA_VER_DOT_STR "0.45.5.0" -#define UNIATA_VER_YEAR 2014 -#define UNIATA_VER_YEAR_STR "2014" +#define UNIATA_VER_SUB_MJ 8 +#define UNIATA_VER_SUB_MN 1 +#define UNIATA_VER_DOT_COMMA 0,45,8,1 +#define UNIATA_VER_DOT_STR "0.45.8.1" +#define UNIATA_VER_YEAR 2015 +#define UNIATA_VER_YEAR_STR "2015"