Index: drivers/storage/ide/uniata/atapi.h =================================================================== --- drivers/storage/ide/uniata/atapi.h (revision 69690) +++ drivers/storage/ide/uniata/atapi.h (working copy) @@ -1486,6 +1486,23 @@ IN struct _HW_CHANNEL* chan ); +VOID +UniataInitIoRes( + IN struct _HW_CHANNEL* chan, + IN ULONG idx, + IN ULONG addr, + IN BOOLEAN MemIo, + IN BOOLEAN Proc + ); + +VOID +UniataInitIoResEx( + IN struct _IORES* IoRes, + IN ULONG addr, + IN BOOLEAN MemIo, + IN BOOLEAN Proc + ); + UCHAR DDKFASTAPI UniataIsIdle( Index: drivers/storage/ide/uniata/bm_devs.h =================================================================== --- drivers/storage/ide/uniata/bm_devs.h (revision 69690) +++ drivers/storage/ide/uniata/bm_devs.h (working copy) @@ -31,6 +31,11 @@ --*/ +#ifndef __IDE_BUSMASTER_DEVICES_H__ +#define __IDE_BUSMASTER_DEVICES_H__ + +#pragma pack(push, 8) + #define IDE_MAX_CHAN 16 #define IDE_DEFAULT_MAX_CHAN 2 // Thanks to SATA Port Multipliers: @@ -47,9 +52,6 @@ //#define UniataGetPioTiming(LunExt) ((LunExt->TransferMode <= ATA_PIO0) ? PIO0_TIMING : 0) #define UniataGetPioTiming(LunExt) 0 //ktp -#ifndef __IDE_BUSMASTER_DEVICES_H__ -#define __IDE_BUSMASTER_DEVICES_H__ - /*#ifdef USER_MODE #define PVEN_STR PCSTR #else // USER_MODE @@ -1275,4 +1277,6 @@ ((pciData)->u.type0.BaseAddresses[5] & ~0x7)) +#pragma pack(pop) + #endif //__IDE_BUSMASTER_H__ Index: drivers/storage/ide/uniata/bsmaster.h =================================================================== --- drivers/storage/ide/uniata/bsmaster.h (revision 69690) +++ drivers/storage/ide/uniata/bsmaster.h (working copy) @@ -31,7 +31,7 @@ Revision History: Code was created by - Alter, Copyright (c) 2002-2014 + Alter, Copyright (c) 2002-2015 Some definitions were taken from FreeBSD 4.3-9.2 ATA driver by Søren Schmidt, Copyright (c) 1998-2014 @@ -64,6 +64,8 @@ #include "uata_ctl.h" +#pragma pack(push, 8) + #define MAX_RETRIES 6 #define RETRY_UDMA2 1 #define RETRY_WDMA 2 @@ -114,6 +116,8 @@ #define PCI_DEV_PROGIF_AHCI_1_0 0x01 +#pragma pack(push, 1) + /* structure for holding DMA address data */ typedef struct BM_DMA_ENTRY { ULONG base; @@ -836,6 +840,7 @@ IDE_AHCI_CMD cmd; // for single internal commands w/o associated AtaReq } IDE_AHCI_CHANNEL_CTL_BLOCK, *PIDE_AHCI_CHANNEL_CTL_BLOCK; +#pragma pack(pop) #define IsBusMaster(pciData) \ ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \ @@ -1199,6 +1204,11 @@ struct _HW_CHANNEL* chan; ULONG Lun; + ULONGLONG errLastLba; + ULONG errBCount; + UCHAR errRetry; + UCHAR errPadding[3]; + #ifdef IO_STATISTICS LONGLONG ModeErrorCount[MAX_RETRIES]; @@ -1483,6 +1493,14 @@ PSCSI_REQUEST_BLOCK Srb ); +extern BOOLEAN +NTAPI +AtapiDmaDBPreSync( + IN PVOID HwDeviceExtension, + PHW_CHANNEL chan, + PSCSI_REQUEST_BLOCK Srb + ); + extern VOID NTAPI AtapiDmaStart( @@ -1865,9 +1883,12 @@ #define VM_VBOX 0x02 #define VM_VMWARE 0x03 #define VM_QEMU 0x04 +#define VM_BOCHS 0x05 #define VM_MAX_KNOWN VM_QEMU extern BOOLEAN WinVer_WDM_Model; +#pragma pack(pop) + #endif //__IDE_BUSMASTER_H__ Index: drivers/storage/ide/uniata/id_ata.cpp =================================================================== --- drivers/storage/ide/uniata/id_ata.cpp (revision 69690) +++ drivers/storage/ide/uniata/id_ata.cpp (working copy) @@ -267,7 +267,9 @@ return; \ } \ if(res->Proc) { \ - } else \ + KdPrint(("PROC io write request @ ch %x, res* %x\n", chan, _port)); \ + ASSERT(FALSE); /* We should never get here */ \ + } \ if(!res->MemIo) { \ ScsiPortWritePort##_Type((_type*)(res->Addr), data); \ } else { \ @@ -302,7 +304,9 @@ return; \ } \ if(res->Proc) { \ - } else \ + KdPrint(("PROC io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \ + ASSERT(FALSE); /* We should never get here */ \ + } \ if(!res->MemIo) { \ ScsiPortWritePort##_Type((_type*)(res->Addr+offs), data); \ } else { \ @@ -335,8 +339,9 @@ return (_type)(-1); \ } \ if(res->Proc) { \ - return 0; \ - } else \ + KdPrint(("PROC io read request @ ch %x, res* %x\n", chan, _port)); \ + ASSERT(FALSE); /* We should never get here */ \ + } \ if(!res->MemIo) { \ /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \ return ScsiPortReadPort##_Type((_type*)(res->Addr)); \ @@ -370,8 +375,9 @@ return (_type)(-1); \ } \ if(res->Proc) { \ - return 0; \ - } else \ + KdPrint(("PROC io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \ + ASSERT(FALSE); /* We should never get here */ \ + } \ if(!res->MemIo) { \ return ScsiPortReadPort##_Type((_type*)(res->Addr+offs)); \ } else { \ @@ -796,6 +802,8 @@ { AtapiStallExecution(30); } + KdPrint2((PRINT_PREFIX " set DFLAGS_REINIT_DMA\n")); + chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_REINIT_DMA; } SelectDrive(chan, DeviceNumber); @@ -1002,6 +1010,7 @@ case ATA_IMMEDIATE: GetStatus(chan, statusByte); if (statusByte & IDE_STATUS_ERROR) { + // Note: some diveces doesn't clear ERR immediately KdPrint2((PRINT_PREFIX " Warning: Immed Status %#x :(\n", statusByte)); if(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_ERROR)) { break; @@ -1008,16 +1017,20 @@ } KdPrint2((PRINT_PREFIX " try to continue\n")); statusByte &= ~IDE_STATUS_ERROR; + + } else { + //KdPrint2((PRINT_PREFIX " send Status %#x\n", statusByte)); } UniataExpectChannelInterrupt(chan, TRUE); // !!!!! InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE); - statusByte = 0; + + statusByte = IDE_STATUS_SUCCESS; break; } - KdPrint2((PRINT_PREFIX " Status %#x\n", statusByte)); + //KdPrint2((PRINT_PREFIX " Status %#x\n", statusByte)); return statusByte; } // end AtaCommand48() @@ -1319,6 +1332,9 @@ chan->RegTranslation[IDX_IO1+j].Addr, statusByteAlt)); } + if(!chan->RegTranslation[IDX_BM_IO].Addr) { + return; + } for(j=0; jFullIdentifyData.VendorAcoustic, deviceExtension->FullIdentifyData.CurrentAcoustic )); - KdPrint2((PRINT_PREFIX "AdvPowerMode %d, cur %d\n", + KdPrint2((PRINT_PREFIX "AdvPowerMode %d\n", deviceExtension->FullIdentifyData.CfAdvPowerMode )); + KdPrint2((PRINT_PREFIX "PowerMngt %d/%d, APM %d/%d\n", + deviceExtension->FullIdentifyData.FeaturesEnabled.PowerMngt, + deviceExtension->FullIdentifyData.FeaturesSupport.PowerMngt, + deviceExtension->FullIdentifyData.FeaturesEnabled.APM, + deviceExtension->FullIdentifyData.FeaturesSupport.APM + )); + // Check out a few capabilities / limitations of the device. if (deviceExtension->FullIdentifyData.RemovableStatus & 1) { // Determine if this drive supports the MSN functions. @@ -1753,7 +1780,26 @@ KdPrint2((PRINT_PREFIX "R-rate %d\n", deviceExtension->FullIdentifyData.NominalMediaRotationRate )); + KdPrint2((PRINT_PREFIX "WC %d/%d, LA %d/%d, WB %d/%d, RB %d/%d, Q %d/%d\n", + deviceExtension->FullIdentifyData.FeaturesEnabled.WriteCache, + deviceExtension->FullIdentifyData.FeaturesSupport.WriteCache, + deviceExtension->FullIdentifyData.FeaturesEnabled.LookAhead, + deviceExtension->FullIdentifyData.FeaturesSupport.LookAhead, + deviceExtension->FullIdentifyData.FeaturesEnabled.WriteBuffer, + deviceExtension->FullIdentifyData.FeaturesSupport.WriteBuffer, + deviceExtension->FullIdentifyData.FeaturesEnabled.ReadBuffer, + deviceExtension->FullIdentifyData.FeaturesSupport.ReadBuffer, + deviceExtension->FullIdentifyData.FeaturesEnabled.Queued, + deviceExtension->FullIdentifyData.FeaturesSupport.Queued + )); + KdPrint2((PRINT_PREFIX "Protected %d/%d status %#x, rev %#x\n", + deviceExtension->FullIdentifyData.FeaturesEnabled.Protected, + deviceExtension->FullIdentifyData.FeaturesSupport.Protected, + deviceExtension->FullIdentifyData.SecurityStatus, + deviceExtension->FullIdentifyData.MasterPasswdRevision + )); + // Read very-old-style drive geometry KdPrint2((PRINT_PREFIX "CHS %#x:%#x:%#x\n", deviceExtension->FullIdentifyData.NumberOfCylinders, @@ -1786,6 +1832,12 @@ } // Check for LBA mode KdPrint2((PRINT_PREFIX "SupportLba flag %#x\n", deviceExtension->FullIdentifyData.SupportLba)); + KdPrint2((PRINT_PREFIX "SupportDMA flag %#x\n", deviceExtension->FullIdentifyData.SupportDma)); + KdPrint2((PRINT_PREFIX "SoftReset %#x\n", deviceExtension->FullIdentifyData.SoftReset)); + KdPrint2((PRINT_PREFIX "SupportIordy %#x, DisableIordy %#x\n", + deviceExtension->FullIdentifyData.SupportIordy, + deviceExtension->FullIdentifyData.DisableIordy + )); KdPrint2((PRINT_PREFIX "MajorRevision %#x\n", deviceExtension->FullIdentifyData.MajorRevision)); KdPrint2((PRINT_PREFIX "UserAddressableSectors %#x\n", deviceExtension->FullIdentifyData.UserAddressableSectors)); if ( deviceExtension->FullIdentifyData.SupportLba @@ -2023,10 +2075,12 @@ if(NumOfSectors) LunExt->NumOfSectors = NumOfSectors; -/* if(deviceExtension->FullIdentifyData.MajorRevision && + } else { + if(deviceExtension->FullIdentifyData.MajorRevision && deviceExtension->FullIdentifyData.DoubleWordIo) { - LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; - }*/ + //LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; + KdPrint2((PRINT_PREFIX "IssueIdentify: DFLAGS_DWORDIO_ENABLED.\n")); + } } ScsiPortMoveMemory(&LunExt->IdentifyData, @@ -2219,7 +2273,7 @@ for (; j < numberChannels; j++) { - KdPrint2((PRINT_PREFIX "AtapiResetController: Reset channel %d\n", j)); + KdPrint2((PRINT_PREFIX "AtapiResetController: Reset lchannel %d[%d]\n", j, deviceExtension->Channel)); chan = &(deviceExtension->chan[j]); MaxLuns = chan->NumberLuns; KdPrint2((PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x, sptr %#x\n", CompleteType, MaxLuns, chan, &chan)); @@ -2228,17 +2282,17 @@ #ifndef UNIATA_CORE while((CurSrb = UniataGetCurRequest(chan))) { + PHW_LU_EXTENSION LunExt; PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension); + i = GET_CDEV(CurSrb); + KdPrint2((PRINT_PREFIX " Lun %x\n", i)); + LunExt = chan->lun[i]; + 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")); @@ -2289,6 +2343,15 @@ } } + if(!ATAPI_DEVICE(chan, i) && AtaReq->bcount && AtaReq->retry < MAX_RETRIES) { + KdPrint2((PRINT_PREFIX "Save retry status %d\n", AtaReq->retry)); + LunExt->errLastLba = AtaReq->lba; + LunExt->errBCount = AtaReq->bcount; + LunExt->errRetry = AtaReq->retry+1; + } else { + LunExt->errRetry = 0; + } + // Clear request tracking fields. AtaReq->WordsLeft = 0; AtaReq->DataBuffer = NULL; @@ -2613,6 +2676,7 @@ GetBaseStatus(chan, statusByte); } // force DMA mode reinit + KdPrint2((PRINT_PREFIX " set DFLAGS_REINIT_DMA\n")); chan->lun[i]->DeviceFlags |= DFLAGS_REINIT_DMA; } #endif //0 @@ -3178,30 +3242,32 @@ 0, ATA_C_F_DIS_RCACHE, ATA_WAIT_BASE_READY); LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED; } - if(LunExt->opt_WriteCacheEnable) { - KdPrint2((PRINT_PREFIX " Try Enable Write Cache\n")); - // If supported & allowed, setup write cacheing - statusByte = AtaCommand(deviceExtension, i, lChannel, - IDE_COMMAND_SET_FEATURES, 0, 0, 0, - 0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_BASE_READY); - // Check for errors. - if (statusByte & IDE_STATUS_ERROR) { - KdPrint2((PRINT_PREFIX - "AtapiHwInitialize: Enable write cacheing on Device %d failed\n", - i)); + if(LunExt->IdentifyData.FeaturesSupport.WriteCache) { + if(LunExt->opt_WriteCacheEnable) { + KdPrint2((PRINT_PREFIX " Try Enable Write Cache\n")); + // If supported & allowed, setup write cacheing + statusByte = AtaCommand(deviceExtension, i, lChannel, + IDE_COMMAND_SET_FEATURES, 0, 0, 0, + 0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_BASE_READY); + // Check for errors. + if (statusByte & IDE_STATUS_ERROR) { + KdPrint2((PRINT_PREFIX + "AtapiHwInitialize: Enable write cacheing on Device %d failed\n", + i)); + LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED; + } else { + LunExt->DeviceFlags |= DFLAGS_WCACHE_ENABLED; + } + } else { + KdPrint2((PRINT_PREFIX " Disable Write Cache\n")); + statusByte = AtaCommand(deviceExtension, i, lChannel, + IDE_COMMAND_SET_FEATURES, 0, 0, 0, + 0, ATA_C_F_DIS_WCACHE, ATA_WAIT_BASE_READY); LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED; - } else { - LunExt->DeviceFlags |= DFLAGS_WCACHE_ENABLED; } - } else { - KdPrint2((PRINT_PREFIX " Disable Write Cache\n")); - statusByte = AtaCommand(deviceExtension, i, lChannel, - IDE_COMMAND_SET_FEATURES, 0, 0, 0, - 0, ATA_C_F_DIS_WCACHE, ATA_WAIT_BASE_READY); - LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED; } - if(LunExt->IdentifyData.FeaturesSupport.PowerMngt || + if(/*LunExt->IdentifyData.FeaturesSupport.PowerMngt ||*/ LunExt->IdentifyData.FeaturesSupport.APM) { if(LunExt->opt_AdvPowerMode) { @@ -3598,7 +3664,7 @@ goto ReturnCallback; } -#ifdef DBG +#ifdef _DEBUG if (!IS_RDP((srb->Cdb[0]))) { KdPrint2((PRINT_PREFIX "AtapiCallBack: Invalid CDB marked as RDP - %#x\n", srb->Cdb[0])); } @@ -4129,7 +4195,7 @@ //SelectDrive(chan, 0); //GetBaseStatus(chan, statusByte); AtapiWritePort1(chan, IDX_IO2_o_Control, - IDE_DC_A_4BIT ); + 0 | IDE_DC_A_4BIT ); //if(chan->NumberLuns) { // SelectDrive(chan, 1); // GetBaseStatus(chan, statusByte); @@ -4696,7 +4762,7 @@ BOOLEAN atapiDev = FALSE; -#ifdef DBG +#ifdef _DEBUG UCHAR Channel; #endif //DBG UCHAR lChannel; @@ -4731,7 +4797,7 @@ lChannel = c; -#ifdef DBG +#ifdef _DEBUG Channel = (UCHAR)(deviceExtension->Channel + lChannel); KdPrint2((PRINT_PREFIX " cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c)); @@ -5264,7 +5330,7 @@ LunExt->BlockIoCount )); LunExt->RecoverCount[AtaReq->retry]++; - if(LunExt->RecoverCount[AtaReq->retry] >= chan->lun[DeviceNumber]->BlockIoCount/3 || + if(LunExt->RecoverCount[AtaReq->retry] >= LunExt->BlockIoCount/3 || (deviceExtension->HwFlags & UNIATA_NO80CHK) ) { #else @@ -5403,6 +5469,9 @@ goto CompleteRequest; } else if (interruptReason == ATAPI_IR_COD_Cmd && (statusByte & IDE_STATUS_DRQ)) { + if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) { + AtapiDmaDBPreSync(HwDeviceExtension, chan, srb); + } // Write the packet. KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n")); // Send CDB to device. @@ -5490,7 +5559,8 @@ statusByte = WaitOnBusy(chan); - if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) { + if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/ + || (wordCount & 1)) { WriteBuffer(chan, AtaReq->DataBuffer, @@ -5628,7 +5698,8 @@ statusByte = WaitOnBusy(chan); - if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) { + if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/ + || (wordCount & 1)) { KdPrint2((PRINT_PREFIX "IdeIntr: Read %#x words\n", wordCount)); @@ -6281,6 +6352,15 @@ interruptReason, statusByte)); + if(g_opt_VirtualMachine == VM_QEMU) { + if(interruptReason == ATAPI_IR_IO_toDev && !(statusByte & IDE_STATUS_DRQ) && !DmaTransfer) { + statusByte = WaitForDrq(chan); + if(statusByte & IDE_STATUS_DRQ) { + goto continue_PIO; + } + } + } + if(OldReqState == REQ_STATE_DPC_WAIT_BUSY0 && AtaReq->WordsLeft == 0) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: pending WAIT_BUSY0. Complete.\n")); @@ -6661,6 +6741,16 @@ AtaReq->bcount)); AtaReq->lba = lba; + if(LunExt->errRetry && + lba == LunExt->errLastLba && + AtaReq->bcount == LunExt->errBCount) { + KdPrint3((PRINT_PREFIX "IdeReadWrite: Retry after BUS_RESET %d @%#I64x (%#x)\n", + LunExt->errRetry, LunExt->errLastLba, LunExt->errBCount)); + if(AtaReq->retry < MAX_RETRIES) { + AtaReq->retry = LunExt->errRetry; + AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE; + } + } // assume best case here // we cannot reinit Dma until previous request is completed @@ -6786,20 +6876,27 @@ if ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) || use_dma) { + if(use_dma) { + AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb); + } statusByte2 = AtaCommand48(deviceExtension, DeviceNumber, lChannel, cmd, lba, (USHORT)(AtaReq->bcount), // (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE), 0, ATA_IMMEDIATE); - if(statusByte2 != IDE_STATUS_WRONG) { +/* if(statusByte2 != IDE_STATUS_WRONG) { GetStatus(chan, statusByte2); - } + }*/ if(statusByte2 & IDE_STATUS_ERROR) { + // Unfortunately, we cannot handle errors in such a way in real life (except known bad blocks). + // Because some devices doesn't reset ERR from previous command immediately after getting new one. + // On the other hand we cannot wait here because of possible timeout condition statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error); KdPrint2((PRINT_PREFIX "IdeReadWrite: status %#x, error %#x\n", statusByte2, statusByte)); return SRB_STATUS_ERROR; } if(use_dma) { + //GetStatus(chan, statusByte2); AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb); } return SRB_STATUS_PENDING; @@ -6842,7 +6939,7 @@ CHECK_INTR_IDLE); // Write next DEV_BSIZE/2*N words. - if (!(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED)) { + if (!(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) || (wordCount & 1)) { KdPrint2((PRINT_PREFIX "IdeReadWrite: Write %#x words\n", wordCount)); @@ -7726,6 +7823,9 @@ KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", statusByte)); #endif //DBG + if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) { + AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb); + } if(g_opt_AtapiSendDisableIntr) { AtapiEnableInterrupts(deviceExtension, lChannel); } @@ -8473,6 +8573,9 @@ AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, regs->bDriveHeadReg); AtapiStallExecution(10); + if(use_dma) { + AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb); + } if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg); Index: drivers/storage/ide/uniata/id_dma.cpp =================================================================== --- drivers/storage/ide/uniata/id_dma.cpp (revision 69690) +++ drivers/storage/ide/uniata/id_dma.cpp (working copy) @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2002-2014 Alexander A. Telyatnikov (Alter) +Copyright (c) 2002-2015 Alexander A. Telyatnikov (Alter) Module Name: id_dma.cpp @@ -254,11 +254,12 @@ BOOLEAN use_AHCI = (deviceExtension->HwFlags & UNIATA_AHCI) ? TRUE : FALSE; ULONG orig_count = count; ULONG max_entries = use_AHCI ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES; - //ULONG max_frag = use_AHCI ? (0x3fffff+1) : (4096); // DEBUG, replace 4096 for procer chipset-specific value + //ULONG max_frag = use_AHCI ? (0x3fffff+1) : (4096); // DEBUG, replace 4096 for proper chipset-specific value ULONG max_frag = deviceExtension->DmaSegmentLength; ULONG seg_align = deviceExtension->DmaSegmentAlignmentMask; if(AtaReq->dma_entries) { + AtaReq->Flags |= REQ_FLAG_DMA_OPERATION; KdPrint2((PRINT_PREFIX "AtapiDmaSetup: already setup, %d entries\n", AtaReq->dma_entries)); return TRUE; } @@ -538,6 +539,41 @@ return TRUE; } // end AtapiDmaDBSync() +BOOLEAN +NTAPI +AtapiDmaDBPreSync( + IN PVOID HwDeviceExtension, + PHW_CHANNEL chan, + PSCSI_REQUEST_BLOCK Srb + ) +{ + PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; + PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension); + + if(!AtaReq->ata.dma_base) { + KdPrint2((PRINT_PREFIX "AtapiDmaDBPreSync: *** !AtaReq->ata.dma_base\n")); + return FALSE; + } +// GetStatus(chan, statusByte2); + if(AtaReq->Flags & REQ_FLAG_DMA_DBUF_PRD) { + KdPrint2((PRINT_PREFIX " DBUF_PRD\n")); + ASSERT(FALSE); + if(deviceExtension->HwFlags & UNIATA_AHCI) { + RtlCopyMemory(chan->DB_PRD, AtaReq->ahci.ahci_cmd_ptr, sizeof(AtaReq->ahci_cmd0)); + } else { + RtlCopyMemory(chan->DB_PRD, &(AtaReq->dma_tab), sizeof(AtaReq->dma_tab)); + } + } + if(!(Srb->SrbFlags & SRB_FLAGS_DATA_IN) && + (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) { + KdPrint2((PRINT_PREFIX " DBUF (Write)\n")); + ASSERT(FALSE); + RtlCopyMemory(chan->DB_IO, AtaReq->DataBuffer, + Srb->DataTransferLength); + } + return TRUE; +} // end AtapiDmaDBPreSync() + VOID NTAPI AtapiDmaStart( @@ -554,15 +590,20 @@ ULONG VendorID = deviceExtension->DevID & 0xffff; ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; - +// UCHAR statusByte2; +/* + GetStatus(chan, statusByte2); KdPrint2((PRINT_PREFIX "AtapiDmaStart: %s on %#x:%#x\n", (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "read" : "write", lChannel, DeviceNumber )); - +*/ if(!AtaReq->ata.dma_base) { KdPrint2((PRINT_PREFIX "AtapiDmaStart: *** !AtaReq->ata.dma_base\n")); return; } + +/* +// GetStatus(chan, statusByte2); if(AtaReq->Flags & REQ_FLAG_DMA_DBUF_PRD) { KdPrint2((PRINT_PREFIX " DBUF_PRD\n")); ASSERT(FALSE); @@ -579,7 +620,7 @@ RtlCopyMemory(chan->DB_IO, AtaReq->DataBuffer, Srb->DataTransferLength); } - +*/ // set flag chan->ChannelCtrlFlags |= CTRFLAGS_DMA_ACTIVE; @@ -791,6 +832,9 @@ KdPrint2((PRINT_PREFIX "AtapiDmaReinit: restore IO mode on Device %d\n", LunExt->Lun)); AtapiDmaInit__(deviceExtension, LunExt); + } else { + KdPrint2((PRINT_PREFIX + "AtapiDmaReinit: LimitedTransferMode == TransferMode = %x (%x)\n", LunExt->TransferMode, LunExt->DeviceFlags)); } exit: @@ -1435,6 +1479,7 @@ /* Intel */ /*********/ + KdPrint2((PRINT_PREFIX "Intel %d\n", Channel)); BOOLEAN udma_ok = FALSE; ULONG idx = 0; ULONG reg40; @@ -1451,6 +1496,7 @@ UCHAR intel_utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 }; if(deviceExtension->DevID == ATA_I82371FB) { + KdPrint2((PRINT_PREFIX " I82371FB\n")); if (wdmamode >= 2 && apiomode >= 4) { ULONG word40; @@ -1473,6 +1519,7 @@ if(deviceExtension->DevID == ATA_ISCH) { ULONG tim; + KdPrint2((PRINT_PREFIX " ISCH\n")); GetPciConfig4(0x80 + dev*4, tim); for(i=udmamode; i>=0; i--) { @@ -1556,6 +1603,7 @@ udma_ok = TRUE; idx = i+8; if(ChipFlags & ICH4_FIX) { + KdPrint2((PRINT_PREFIX " ICH4_FIX udma\n")); return; } break; @@ -1573,6 +1621,7 @@ udma_ok = TRUE; idx = i+5; if(ChipFlags & ICH4_FIX) { + KdPrint2((PRINT_PREFIX " ICH4_FIX wdma\n")); return; } break; @@ -1589,10 +1638,13 @@ GetPciConfig1(0x44, reg44); /* Allow PIO/WDMA timing controls. */ + reg40 &= ~0x00ff00ff; + reg40 |= 0x40774077; + mask40 = 0x000000ff; /* Set PIO/WDMA timings. */ if(!(DeviceNumber & 1)) { - mask40 |= 0x00003300; + mask40 = 0x00003300; new40 = ((USHORT)(intel_timings[idx]) << 8); } else { mask44 = 0x0f; @@ -1599,7 +1651,6 @@ new44 = ((intel_timings[idx] & 0x30) >> 2) | (intel_timings[idx] & 0x03); } - new40 |= 0x00004077; if (Channel) { mask40 <<= 16; @@ -1608,6 +1659,7 @@ new44 <<= 4; } + KdPrint2((PRINT_PREFIX " 0x40 %x/%x, 0x44 %x/%x\n", mask40, new40, mask44, new44)); SetPciConfig4(0x40, (reg40 & ~mask40) | new40); SetPciConfig1(0x44, (reg44 & ~mask44) | new44); @@ -1656,12 +1708,6 @@ return; } } - /* try generic DMA, use hpt_timing() */ - if (wdmamode >= 0 && apiomode >= 4) { - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) { - return; - } - } AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); promise_timing(deviceExtension, dev, ATA_PIO0 + apiomode); return; @@ -2258,14 +2304,22 @@ ULONG slotNumber = deviceExtension->slotNumber; ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; - ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK; - ULONG timing = 0; + ULONG port = 0x60 + (dev<<2); if(mode == ATA_PIO5) mode = ATA_PIO4; + if(mode < ATA_PIO0) + mode = ATA_PIO0; + +#if 0 +// **** FreeBSD code **** + + ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; + ULONG timing = 0; + switch(ChipType) { case PROLD: switch (mode) { @@ -2306,7 +2360,80 @@ default: return; } - SetPciConfig4(0x60 + (dev<<2), timing); + if(!timing) { + return; + } + SetPciConfig4(port, timing); + +#else +// **** Linux code **** + + UCHAR r_bp, r_cp, r_ap; + ULONG i; + + static UCHAR udma_timing[6][2] = { + { 0x60, 0x03 }, /* 33 Mhz Clock */ + { 0x40, 0x02 }, + { 0x20, 0x01 }, + { 0x40, 0x02 }, /* 66 Mhz Clock */ + { 0x20, 0x01 }, + { 0x20, 0x01 } + }; + static UCHAR mdma_timing[3][2] = { + { 0xe0, 0x0f }, + { 0x60, 0x04 }, + { 0x60, 0x03 }, + }; + static USHORT pio_timing[5] = { + 0x0913, 0x050C , 0x0308, 0x0206, 0x0104 + }; + + if(mode > ATA_UDMA5) { + return; + } + + if(mode > ATA_WDMA0) { + + GetPciConfig1(port+1, r_bp); + GetPciConfig1(port+2, r_cp); + + r_bp &= ~0xE0; + r_cp &= ~0x0F; + + if(mode >= ATA_UDMA0) { + i = mode - ATA_UDMA0; + r_bp |= udma_timing[i][0]; + r_cp |= udma_timing[i][1]; + + } else { + i = mode - ATA_WDMA0; + r_bp |= mdma_timing[i][0]; + r_cp |= mdma_timing[i][1]; + } + SetPciConfig1(port+1, r_bp); + SetPciConfig1(port+2, r_cp); + } else + if(mode <= ATA_PIO5) { + GetPciConfig1(port+0, r_ap); + GetPciConfig1(port+1, r_bp); + + i = mode - ATA_PIO0; + r_ap &= ~0x3F; /* Preserve ERRDY_EN, SYNC_IN */ + r_bp &= ~0x1F; + r_ap |= (UCHAR)(pio_timing[i] >> 8); + r_bp |= (UCHAR)(pio_timing[i] & 0xFF); + +// if (ata_pio_need_iordy(adev)) + r_ap |= 0x20; /* IORDY enable */ +// if (adev->class == ATA_DEV_ATA) +// r_ap |= 0x10; /* FIFO enable */ + + SetPciConfig1(port+0, r_ap); + SetPciConfig1(port+1, r_bp); + } + +#endif + } // end promise_timing() Index: drivers/storage/ide/uniata/id_init.cpp =================================================================== --- drivers/storage/ide/uniata/id_init.cpp (revision 69690) +++ drivers/storage/ide/uniata/id_init.cpp (working copy) @@ -397,8 +397,6 @@ if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) { return STATUS_UNSUCCESSFUL; } - // DEBUG, we shall return success when AHCI is completly supported - //return STATUS_NOT_FOUND; return STATUS_SUCCESS; } @@ -570,8 +568,7 @@ ScsiPortFreeDeviceBase(HwDeviceExtension, deviceExtension->BaseIoAddressBM_0); - deviceExtension->BaseIoAddressBM_0.Addr = 0; - deviceExtension->BaseIoAddressBM_0.MemIo = 0; + UniataInitIoResEx(&deviceExtension->BaseIoAddressBM_0, 0, FALSE, FALSE); deviceExtension->BusMaster = DMA_MODE_NONE; deviceExtension->MaxTransferMode = ATA_PIO4; break; @@ -648,15 +645,24 @@ deviceExtension->HwFlags &= ~UNIATA_AHCI; } break; + default: + if(!ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)) { + KdPrint2((PRINT_PREFIX "No BAR5, try BM\n")); + ChipFlags &= ~UNIATA_AHCI; + deviceExtension->HwFlags &= ~UNIATA_AHCI; + } + break; } } if(ChipFlags & UNIATA_AHCI) { + deviceExtension->NumberChannels = 0; if(!UniataAhciDetect(HwDeviceExtension, pciData, ConfigInfo)) { KdPrint2((PRINT_PREFIX " AHCI detect failed\n")); return STATUS_UNSUCCESSFUL; } + } else if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) { return STATUS_UNSUCCESSFUL; @@ -682,13 +688,13 @@ chan = &deviceExtension->chan[c]; for (i=0; i<=IDX_IO1_SZ; i++) { - chan->RegTranslation[IDX_IO1+i].Addr = BaseIoAddress1 + i + (unit10 ? 8 : 0); + UniataInitIoRes(chan, IDX_IO1+i, BaseIoAddress1 + i + (unit10 ? 8 : 0), FALSE, FALSE); } - chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseIoAddress2 + 2 + (unit10 ? 4 : 0); + UniataInitIoRes(chan, IDX_IO2_AltStatus, BaseIoAddress2 + 2 + (unit10 ? 4 : 0), FALSE, FALSE); UniataInitSyncBaseIO(chan); for (i=0; i<=IDX_BM_IO_SZ; i++) { - chan->RegTranslation[IDX_BM_IO+i].Addr = BaseIoAddressBM + i + (c * sizeof(IDE_BUSMASTER_REGISTERS)); + UniataInitIoRes(chan, IDX_BM_IO+i, BaseIoAddressBM + i + (c * sizeof(IDE_BUSMASTER_REGISTERS)), FALSE, FALSE); } // SATA not supported yet @@ -714,17 +720,13 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); for(c=0; cNumberChannels; c++) { chan = &deviceExtension->chan[c]; - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + (c << 6); - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 4 + (c << 6); - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 8 + (c << 6); - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + (c << 6), MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + 4 + (c << 6), MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + 8 + (c << 6), MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } @@ -751,8 +753,7 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); /* BAR3 -> res2 */ BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, @@ -765,8 +766,7 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressBM_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressBM_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressBM_0, BaseMemAddress, MemIo, FALSE); if(!(ChipFlags & UNIATA_SATA)) { UCHAR reg48; @@ -789,31 +789,23 @@ offs7 = c << 7; for (i=0; i<=IDX_IO1_SZ; i++) { - chan->RegTranslation[IDX_IO1+i].Addr = BaseMemAddress + 0x200 + (i << 2) + offs7; - chan->RegTranslation[IDX_IO1+i].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO1+i, BaseMemAddress + 0x200 + (i << 2) + offs8, MemIo, FALSE); } - chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + 0x238 + offs7; - chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO2_AltStatus, BaseMemAddress + 0x238 + offs7, MemIo, FALSE); UniataInitSyncBaseIO(chan); - chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + 0x260 + offs7; - chan->RegTranslation[IDX_BM_Command].MemIo = MemIo; - chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + 0x244 + offs7; - chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo; - chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + (c << 2); - chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo; + UniataInitIoRes(chan, IDX_BM_Command, BaseMemAddress + 0x260 + offs7, MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_PRD_Table, BaseMemAddress + 0x244 + offs7, MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_DeviceSpecific0, BaseMemAddress + (c << 2), MemIo, FALSE); if((ChipFlags & PRSATA) || ((ChipFlags & PRCMBO) && c<2)) { KdPrint2((PRINT_PREFIX "Promise SATA\n")); - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0x400 + offs7; - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 0x404 + offs7; - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 0x408 + offs7; - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + 0x400 + offs7, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + 0x404 + offs7, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + 0x408 + offs7, MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } else { @@ -864,8 +856,7 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); for(c=0; cNumberChannels; c++) { ULONG unit01 = (c & 1); @@ -875,25 +866,16 @@ if(deviceExtension->AltRegMap) { for (i=0; i<=IDX_IO1_SZ; i++) { - chan->RegTranslation[IDX_IO1+i].Addr = BaseMemAddress + 0x80 + i + (unit01 << 6) + (unit10 << 8); - chan->RegTranslation[IDX_IO1+i].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO1+i, BaseMemAddress + 0x80 + i + (unit01 << 6) + (unit10 << 8), MemIo, FALSE); } - chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + 0x8a + (unit01 << 6) + (unit10 << 8); - chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO2_AltStatus, BaseMemAddress + 0x8a + (unit01 << 6) + (unit10 << 8), MemIo, FALSE); UniataInitSyncBaseIO(chan); - chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + 0x00 + (unit01 << 3) + (unit10 << 8); - chan->RegTranslation[IDX_BM_Command].MemIo = MemIo; - chan->RegTranslation[IDX_BM_Status].Addr = BaseMemAddress + 0x02 + (unit01 << 3) + (unit10 << 8); - chan->RegTranslation[IDX_BM_Status].MemIo = MemIo; - chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + 0x04 + (unit01 << 3) + (unit10 << 8); - chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo; - //chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0xa1 + (unit01 << 6) + (unit10 << 8); - //chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo; - chan->RegTranslation[IDX_BM_DeviceSpecific0].Addr = BaseMemAddress + 0x10 + (unit01 << 3) + (unit10 << 8); - chan->RegTranslation[IDX_BM_DeviceSpecific0].MemIo = MemIo; - chan->RegTranslation[IDX_BM_DeviceSpecific1].Addr = BaseMemAddress + 0x40 + (unit01 << 2) + (unit10 << 8); - chan->RegTranslation[IDX_BM_DeviceSpecific1].MemIo = MemIo; + UniataInitIoRes(chan, IDX_BM_Command, BaseMemAddress + 0x00 + (unit01 << 3) + (unit10 << 8), MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_Status, BaseMemAddress + 0x02 + (unit01 << 3) + (unit10 << 8), MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_PRD_Table, BaseMemAddress + 0x04 + (unit01 << 3) + (unit10 << 8), MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_DeviceSpecific0, BaseMemAddress + 0x10 + (unit01 << 3) + (unit10 << 8), MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_DeviceSpecific1, BaseMemAddress + 0x40 + (unit01 << 2) + (unit10 << 8), MemIo, FALSE); } if(chan->MaxTransferMode < ATA_SA150) { @@ -901,12 +883,9 @@ KdPrint2((PRINT_PREFIX "No SATA regs for PATA part\n")); } else if(ChipFlags & UNIATA_SATA) { - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0x104 + (unit01 << 7) + (unit10 << 8); - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 0x108 + (unit01 << 7) + (unit10 << 8); - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 0x100 + (unit01 << 7) + (unit10 << 8); - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + 0x104 + (unit01 << 7) + (unit10 << 8), MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + 0x108 + (unit01 << 2) + (unit10 << 8), MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + 0x100 + (unit01 << 2) + (unit10 << 8), MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } @@ -935,8 +914,7 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); for(c=0; cNumberChannels; c++) { ULONG offs = c*0x100; @@ -943,26 +921,18 @@ chan = &deviceExtension->chan[c]; for (i=0; i<=IDX_IO1_SZ; i++) { - chan->RegTranslation[IDX_IO1+i].Addr = BaseMemAddress + offs + i*4; - chan->RegTranslation[IDX_IO1+i].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO1+i, BaseMemAddress + offs + i*4, MemIo, FALSE); } - chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + offs + 0x20; - chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO2_AltStatus, BaseMemAddress + offs + 0x20, MemIo, FALSE); UniataInitSyncBaseIO(chan); - chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + offs + 0x30; - chan->RegTranslation[IDX_BM_Command].MemIo = MemIo; - chan->RegTranslation[IDX_BM_Status].Addr = BaseMemAddress + offs + 0x32; - chan->RegTranslation[IDX_BM_Status].MemIo = MemIo; - chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + offs + 0x34; - chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo; + UniataInitIoRes(chan, IDX_BM_Command, BaseMemAddress + offs + 0x30, MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_Status, BaseMemAddress + offs + 0x32, MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_PRD_Table, BaseMemAddress + offs + 0x34, MemIo, FALSE); - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + offs + 0x40; - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + offs + 0x44; - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + offs + 0x48; - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + offs + 0x40, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + offs + 0x44, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + offs + 0x48, MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } @@ -1039,19 +1009,15 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); for(c=0; cNumberChannels; c++) { ULONG offs = c << (SIS_182 ? 5 : 6); chan = &deviceExtension->chan[c]; - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0 + offs; - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 4 + offs; - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 8 + offs; - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + 0 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + 4 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + 8 + offs, MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } @@ -1092,8 +1058,7 @@ KdPrint2((PRINT_PREFIX "MemIo\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); } if(/*deviceExtension->*/BaseMemAddress) { KdPrint2((PRINT_PREFIX "UniataChipDetect: BAR5 %x\n", /*deviceExtension->*/BaseMemAddress)); @@ -1114,13 +1079,13 @@ BaseIo = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, c, 0, /*0x80*/ sizeof(IDE_REGISTERS_1) + sizeof(IDE_REGISTERS_2)*2); for (i=0; i<=IDX_IO1_SZ; i++) { - chan->RegTranslation[IDX_IO1+i].Addr = BaseIo + i; + UniataInitIoRes(chan, IDX_IO1+i, BaseIo + i, FALSE, FALSE); } - chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseIo + sizeof(IDE_REGISTERS_1) + 2; + UniataInitIoRes(chan, IDX_IO2_AltStatus, BaseIo + sizeof(IDE_REGISTERS_1) + 2, FALSE, FALSE); UniataInitSyncBaseIO(chan); for (i=0; i<=IDX_BM_IO_SZ; i++) { - chan->RegTranslation[IDX_BM_IO+i].Addr = BaseIoAddressBM_0 + sizeof(IDE_BUSMASTER_REGISTERS)*c + i; + UniataInitIoRes(chan, IDX_BM_IO+i, BaseIoAddressBM_0 + sizeof(IDE_BUSMASTER_REGISTERS)*c + i, FALSE, FALSE); } } @@ -1130,17 +1095,13 @@ if((ChipFlags & VIABAR) && (c==2)) { // Do not setup SATA registers for PATA part for (i=0; i<=IDX_SATA_IO_SZ; i++) { - chan->RegTranslation[IDX_SATA_IO+i].Addr = 0; - chan->RegTranslation[IDX_SATA_IO+i].MemIo = 0; + UniataInitIoRes(chan, IDX_SATA_IO+i, 0, FALSE, FALSE); } break; } - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + (c * IoSize); - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 4 + (c * IoSize); - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 8 + (c * IoSize); - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + (c * IoSize), MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + 4 + (c * IoSize), MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + 8 + (c * IoSize), MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } @@ -1169,8 +1130,7 @@ MemIo = TRUE; } deviceExtension->AltRegMap = TRUE; // inform generic resource allocator - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); for(c=0; cNumberChannels; c++) { ULONG offs = 0x200 + c*0x200; @@ -1177,41 +1137,24 @@ chan = &deviceExtension->chan[c]; for (i=0; i<=IDX_IO1_SZ; i++) { - chan->RegTranslation[IDX_IO1+i].MemIo = MemIo; - chan->RegTranslation[IDX_IO1_o+i].MemIo = MemIo; + UniataInitIoRes(chan, IDX_BM_IO+i, BaseMemAddress + i*4 + offs, MemIo, FALSE); } - chan->RegTranslation[IDX_IO1_i_Data ].Addr = BaseMemAddress + 0x00 + offs; - chan->RegTranslation[IDX_IO1_i_Error ].Addr = BaseMemAddress + 0x04 + offs; - chan->RegTranslation[IDX_IO1_i_BlockCount ].Addr = BaseMemAddress + 0x08 + offs; - chan->RegTranslation[IDX_IO1_i_BlockNumber ].Addr = BaseMemAddress + 0x0c + offs; - chan->RegTranslation[IDX_IO1_i_CylinderLow ].Addr = BaseMemAddress + 0x10 + offs; - chan->RegTranslation[IDX_IO1_i_CylinderHigh].Addr = BaseMemAddress + 0x14 + offs; - chan->RegTranslation[IDX_IO1_i_DriveSelect ].Addr = BaseMemAddress + 0x18 + offs; - chan->RegTranslation[IDX_IO1_i_Status ].Addr = BaseMemAddress + 0x1c + offs; - UniataInitSyncBaseIO(chan); - chan->RegTranslation[IDX_IO1_o_Command ].Addr = BaseMemAddress + 0x1d + offs; - chan->RegTranslation[IDX_IO1_o_Feature ].Addr = BaseMemAddress + 0x06 + offs; - chan->RegTranslation[IDX_IO2_o_Control ].Addr = BaseMemAddress + 0x29 + offs; + UniataInitIoRes(chan, IDX_IO1_o_Command, BaseMemAddress + 0x1d + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_IO1_o_Feature, BaseMemAddress + 0x06 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_IO2_o_Control, BaseMemAddress + 0x29 + offs, MemIo, FALSE); - chan->RegTranslation[IDX_IO2_AltStatus].Addr = BaseMemAddress + 0x28 + offs; - chan->RegTranslation[IDX_IO2_AltStatus].MemIo = MemIo; + UniataInitIoRes(chan, IDX_IO2_AltStatus, BaseMemAddress + 0x28 + offs, MemIo, FALSE); - chan->RegTranslation[IDX_BM_Command].Addr = BaseMemAddress + offs + 0x70; - chan->RegTranslation[IDX_BM_Command].MemIo = MemIo; - chan->RegTranslation[IDX_BM_Status].Addr = BaseMemAddress + offs + 0x72; - chan->RegTranslation[IDX_BM_Status].MemIo = MemIo; - chan->RegTranslation[IDX_BM_PRD_Table].Addr = BaseMemAddress + offs + 0x74; - chan->RegTranslation[IDX_BM_PRD_Table].MemIo = MemIo; + UniataInitIoRes(chan, IDX_BM_Command, BaseMemAddress + 0x70 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_Status, BaseMemAddress + 0x72 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_BM_PRD_Table, BaseMemAddress + 0x74 + offs, MemIo, FALSE); - chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + 0x100 + offs; - chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + 0x104 + offs; - chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo; - chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + 0x108 + offs; - chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo; + UniataInitIoRes(chan, IDX_SATA_SStatus, BaseMemAddress + 0x100 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SError, BaseMemAddress + 0x104 + offs, MemIo, FALSE); + UniataInitIoRes(chan, IDX_SATA_SControl, BaseMemAddress + 0x108 + offs, MemIo, FALSE); chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE; } @@ -1232,7 +1175,11 @@ //KdPrint2((PRINT_PREFIX "AHCI not supported yet\n")); //return FALSE; KdPrint2((PRINT_PREFIX "try run AHCI\n")); - break; + if(ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)) { + break; + } + KdPrint2((PRINT_PREFIX "No BAR5, try BM\n")); + deviceExtension->HwFlags &= ~UNIATA_AHCI; } BaseIoAddressBM = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber, 4, 0, sizeof(IDE_BUSMASTER_REGISTERS)); @@ -1243,15 +1190,13 @@ KdPrint2((PRINT_PREFIX "MemIo[4]\n")); MemIo = TRUE; } - deviceExtension->BaseIoAddressBM_0.Addr = BaseIoAddressBM; - deviceExtension->BaseIoAddressBM_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressBM_0, BaseIoAddressBM, MemIo, FALSE); tmp8 = AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),IDX_BM_Status); KdPrint2((PRINT_PREFIX "BM status: %x\n", tmp8)); /* cleanup */ ScsiPortFreeDeviceBase(HwDeviceExtension, (PCHAR)BaseIoAddressBM); - deviceExtension->BaseIoAddressBM_0.Addr = 0; - deviceExtension->BaseIoAddressBM_0.MemIo = 0; + UniataInitIoResEx(&deviceExtension->BaseIoAddressBM_0, 0, 0, FALSE); if(tmp8 == 0xff) { KdPrint2((PRINT_PREFIX "invalid BM status, keep AHCI mode\n")); @@ -1287,8 +1232,7 @@ MemIo = TRUE; } } - deviceExtension->BaseIoAddressSATA_0.Addr = BaseMemAddress; - deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo; + UniataInitIoResEx(&deviceExtension->BaseIoAddressSATA_0, BaseMemAddress, MemIo, FALSE); for(c=0; cNumberChannels; c++) { chan = &deviceExtension->chan[c]; @@ -1337,10 +1281,8 @@ if(!(ChipFlags & ICH7) && BaseMemAddress) { KdPrint2((PRINT_PREFIX "BaseMemAddress[5] -> 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; - chan->RegTranslation[IDX_INDEXED_DATA].MemIo = MemIo; + UniataInitIoRes(chan, IDX_INDEXED_ADDR, BaseMemAddress + 0, MemIo, FALSE); + UniataInitIoRes(chan, IDX_INDEXED_DATA, BaseMemAddress + 4, MemIo, FALSE); } if((ChipFlags & ICH5) || BaseMemAddress) { @@ -1353,12 +1295,9 @@ if(ChipFlags & ICH7) { KdPrint2((PRINT_PREFIX "ICH7 way\n")); } - chan->RegTranslation[IDX_SATA_SStatus].Addr = 0x200*c + 0; // this is fake non-zero value - chan->RegTranslation[IDX_SATA_SStatus].Proc = 1; - chan->RegTranslation[IDX_SATA_SError].Addr = 0x200*c + 2; // this is fake non-zero value - chan->RegTranslation[IDX_SATA_SError].Proc = 1; - chan->RegTranslation[IDX_SATA_SControl].Addr = 0x200*c + 1; // this is fake non-zero value - chan->RegTranslation[IDX_SATA_SControl].Proc = 1; + UniataInitIoRes(chan, IDX_SATA_SStatus, 0x200*c + 0, FALSE, TRUE); // this is fake non-zero value + UniataInitIoRes(chan, IDX_SATA_SError, 0x200*c + 2, FALSE, TRUE); + UniataInitIoRes(chan, IDX_SATA_SControl, 0x200*c + 1, FALSE, TRUE); } } @@ -1811,8 +1750,11 @@ if(tmp32) { LunExt->DeviceFlags |= DFLAGS_HIDDEN; } + tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"Exclude", 0); + if(tmp32) { + LunExt->DeviceFlags |= DFLAGS_HIDDEN; + } - return; } // end UniAtaReadLunConfig() @@ -2713,8 +2655,7 @@ for(c=0; cNumberChannels; c++) { chan = &deviceExtension->chan[c]; for (i=0; iRegTranslation[IDX_BM_IO+i].Addr = BaseIoAddressBM_0 ? ((ULONGIO_PTR)BaseIoAddressBM_0 + i) : 0; - chan->RegTranslation[IDX_BM_IO+i].MemIo = MemIo; + UniataInitIoRes(chan, IDX_BM_IO+i, BaseIoAddressBM_0 ? ((ULONGIO_PTR)BaseIoAddressBM_0 + i) : 0, MemIo, FALSE); } if(BaseIoAddressBM_0) { BaseIoAddressBM_0++; @@ -2734,12 +2675,10 @@ ULONG i; for (i=0; iRegTranslation[IDX_IO1+i].Addr = BaseIoAddress1 ? ((ULONGIO_PTR)BaseIoAddress1 + i) : 0; - chan->RegTranslation[IDX_IO1+i].MemIo = FALSE; + UniataInitIoRes(chan, IDX_IO1+i, BaseIoAddress1 ? ((ULONGIO_PTR)BaseIoAddress1 + i) : 0, FALSE, FALSE); } for (i=0; iRegTranslation[IDX_IO2+i].Addr = BaseIoAddress2 ? ((ULONGIO_PTR)BaseIoAddress2 + i) : 0; - chan->RegTranslation[IDX_IO2+i].MemIo = FALSE; + UniataInitIoRes(chan, IDX_IO2+i, BaseIoAddress2 ? ((ULONGIO_PTR)BaseIoAddress2 + i) : 0, FALSE, FALSE); } UniataInitSyncBaseIO(chan); return; @@ -2757,6 +2696,39 @@ } // end UniataInitSyncBaseIO() VOID +UniataInitIoRes( + IN PHW_CHANNEL chan, + IN ULONG idx, + IN ULONG addr, + IN BOOLEAN MemIo, + IN BOOLEAN Proc + ) +{ + if(!addr) { + MemIo = Proc = FALSE; + } + chan->RegTranslation[idx].Addr = addr; + chan->RegTranslation[idx].MemIo = MemIo; + chan->RegTranslation[idx].Proc = Proc; +} // end UniataInitIoRes() + +VOID +UniataInitIoResEx( + IN PIORES IoRes, + IN ULONG addr, + IN BOOLEAN MemIo, + IN BOOLEAN Proc + ) +{ + if(!addr) { + MemIo = Proc = FALSE; + } + IoRes->Addr = addr; + IoRes->MemIo = MemIo; + IoRes->Proc = Proc; +} // end UniataInitIoResEx() + +VOID NTAPI AtapiSetupLunPtrs( IN PHW_CHANNEL chan, Index: drivers/storage/ide/uniata/id_probe.cpp =================================================================== --- drivers/storage/ide/uniata/id_probe.cpp (revision 69690) +++ drivers/storage/ide/uniata/id_probe.cpp (working copy) @@ -297,6 +297,7 @@ // PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; // PVOID HwDeviceExtension; PHW_DEVICE_EXTENSION deviceExtension = NULL; + PCHAR PciDevMap = NULL; PCI_SLOT_NUMBER slotData; PCI_COMMON_CONFIG pciData; ULONG busNumber; @@ -336,6 +337,9 @@ deviceStrPtr = deviceString; slotData.u.AsULONG = 0; + if(!maxPciBus) { + return(SP_RETURN_NOT_FOUND); + } /*HwDeviceExtension =*/ deviceExtension = (PHW_DEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_DEVICE_EXTENSION)); if(!deviceExtension) { @@ -342,13 +346,26 @@ return(SP_RETURN_NOT_FOUND); } RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); + PciDevMap = (PCHAR)ExAllocatePool(NonPagedPool, maxPciBus*PCI_MAX_DEVICES); + if(!PciDevMap) { + goto exit; + } + RtlZeroMemory(PciDevMap, maxPciBus*PCI_MAX_DEVICES); for(pass=0; pass<3; pass++) { + no_buses = FALSE; for(busNumber=0 ;busNumber 31*/ || + (IrqForCompat == 0xff)) { + IrqForCompat = 0x0b; + KdPrint2((PRINT_PREFIX "default to IRQ 11\n")); } - if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIMode", 0)) { - KdPrint2((PRINT_PREFIX "try switch to native mode\n")); - IrqForCompat = (UCHAR)AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIModeIRQ", 0xff); - KdPrint2((PRINT_PREFIX "IrqForCompat = %#x\n", IrqForCompat)); - if((IrqForCompat & 0xffffff00) /*|| - (IrqForCompat & 0xff) > 31*/ || - (IrqForCompat == 0xff)) { - IrqForCompat = 0x0b; - KdPrint2((PRINT_PREFIX "default to IRQ 11\n")); + //ChangePciConfig1(0x09, a | PCI_IDE_PROGIF_NATIVE_ALL); // ProgIf + pciData.ProgIf |= PCI_IDE_PROGIF_NATIVE_ALL; + HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, + &(pciData.ProgIf), + offsetof(PCI_COMMON_CONFIG, ProgIf), + sizeof(pciData.ProgIf)); + + // reread config space + busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, + &pciData, PCI_COMMON_HDR_LENGTH); + // check if the device have switched to Native Mode + if(IsMasterDev(&pciData)) { + KdPrint2((PRINT_PREFIX "Can't switch to native mode\n")); + } else { + KdPrint2((PRINT_PREFIX "switched to native mode\n")); + KdPrint2((PRINT_PREFIX "InterruptPin = %#x\n", pciData.u.type0.InterruptPin)); + KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); + // check if IRQ is assigned to device + if(!(pciData.u.type0.InterruptLine) || + (pciData.u.type0.InterruptLine == 0xff)) { + KdPrint2((PRINT_PREFIX "assign interrupt for device\n")); + pciData.u.type0.InterruptLine = IrqForCompat; + HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, + &(pciData.u.type0.InterruptLine), + offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine), + sizeof(pciData.u.type0.InterruptLine)); + } else { + KdPrint2((PRINT_PREFIX "Auto-assigned interrupt line %#x\n", + pciData.u.type0.InterruptLine)); + IrqForCompat = pciData.u.type0.InterruptLine; } - - //ChangePciConfig1(0x09, a | PCI_IDE_PROGIF_NATIVE_ALL); // ProgIf - pciData.ProgIf |= PCI_IDE_PROGIF_NATIVE_ALL; - HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, - &(pciData.ProgIf), - offsetof(PCI_COMMON_CONFIG, ProgIf), - sizeof(pciData.ProgIf)); - + KdPrint2((PRINT_PREFIX "reread config space\n")); // reread config space busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, &pciData, PCI_COMMON_HDR_LENGTH); - // check if the device have switched to Native Mode - if(IsMasterDev(&pciData)) { - KdPrint2((PRINT_PREFIX "Can't switch to native mode\n")); - } else { - KdPrint2((PRINT_PREFIX "switched to native mode\n")); - KdPrint2((PRINT_PREFIX "InterruptPin = %#x\n", pciData.u.type0.InterruptPin)); - KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); - // check if IRQ is assigned to device - if(!(pciData.u.type0.InterruptLine) || - (pciData.u.type0.InterruptLine == 0xff)) { - KdPrint2((PRINT_PREFIX "assign interrupt for device\n")); - pciData.u.type0.InterruptLine = IrqForCompat; - HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, - &(pciData.u.type0.InterruptLine), - offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine), - sizeof(pciData.u.type0.InterruptLine)); - } else { - KdPrint2((PRINT_PREFIX "Auto-assigned interrupt line %#x\n", - pciData.u.type0.InterruptLine)); - IrqForCompat = pciData.u.type0.InterruptLine; - } - KdPrint2((PRINT_PREFIX "reread config space\n")); + KdPrint2((PRINT_PREFIX "busDataRead = %#x\n", busDataRead)); + KdPrint2((PRINT_PREFIX "reread InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); + // check if we have successfully assigned IRQ to device + if((pciData.u.type0.InterruptLine != IrqForCompat) || + (pciData.u.type0.InterruptLine == 0xff) || + !pciData.u.type0.InterruptLine) { + KdPrint2((PRINT_PREFIX "can't assign interrupt for device, revert to compat mode\n")); + pciData.u.type0.InterruptLine = 0xff; + KdPrint2((PRINT_PREFIX "set IntrLine to 0xff\n")); + HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, + &(pciData.u.type0.InterruptLine), + offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine), + sizeof(pciData.u.type0.InterruptLine)); + KdPrint2((PRINT_PREFIX "clear PCI_IDE_PROGIF_NATIVE_ALL\n")); + pciData.ProgIf &= ~PCI_IDE_PROGIF_NATIVE_ALL; + HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, + &(pciData.ProgIf), + offsetof(PCI_COMMON_CONFIG, ProgIf), + sizeof(pciData.ProgIf)); // reread config space + KdPrint2((PRINT_PREFIX "reread config space on revert\n")); busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, &pciData, PCI_COMMON_HDR_LENGTH); - KdPrint2((PRINT_PREFIX "busDataRead = %#x\n", busDataRead)); - KdPrint2((PRINT_PREFIX "reread InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); - // check if we have successfully assigned IRQ to device - if((pciData.u.type0.InterruptLine != IrqForCompat) || - (pciData.u.type0.InterruptLine == 0xff) || - !pciData.u.type0.InterruptLine) { - KdPrint2((PRINT_PREFIX "can't assign interrupt for device, revert to compat mode\n")); - pciData.u.type0.InterruptLine = 0xff; - KdPrint2((PRINT_PREFIX "set IntrLine to 0xff\n")); - HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, - &(pciData.u.type0.InterruptLine), - offsetof(PCI_COMMON_CONFIG, u.type0.InterruptLine), - sizeof(pciData.u.type0.InterruptLine)); - KdPrint2((PRINT_PREFIX "clear PCI_IDE_PROGIF_NATIVE_ALL\n")); - pciData.ProgIf &= ~PCI_IDE_PROGIF_NATIVE_ALL; - HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG, - &(pciData.ProgIf), - offsetof(PCI_COMMON_CONFIG, ProgIf), - sizeof(pciData.ProgIf)); - // reread config space - KdPrint2((PRINT_PREFIX "reread config space on revert\n")); - busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG, - &pciData, PCI_COMMON_HDR_LENGTH); - } else { - KdPrint2((PRINT_PREFIX "Assigned interrupt %#x for device\n", IrqForCompat)); - KdPrint2((PRINT_PREFIX "continue detection on next round\n")); - continue; - } + } else { + KdPrint2((PRINT_PREFIX "Assigned interrupt %#x for device\n", IrqForCompat)); + KdPrint2((PRINT_PREFIX "continue detection on next round\n")); + continue; } } - } else - if(pass == 2) { - if(IsMasterDev(&pciData)) - continue; } + } else + if(pass == 2) { + if(IsMasterDev(&pciData)) + continue; + } /* if(known) { - RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION)); - } else {*/ - sprintf((PCHAR)vendorStrPtr, "%4.4lx", VendorID); - sprintf((PCHAR)deviceStrPtr, "%4.4lx", DeviceID); + RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION)); + } else {*/ + sprintf((PCHAR)vendorStrPtr, "%4.4lx", VendorID); + sprintf((PCHAR)deviceStrPtr, "%4.4lx", DeviceID); - RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4); - RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4); + RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4); + RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4); - newBMListPtr->nVendorId = VendorID; - newBMListPtr->VendorId = (PCHAR)&(newBMListPtr->VendorIdStr); - newBMListPtr->VendorIdLength = 4; - newBMListPtr->nDeviceId = DeviceID; - newBMListPtr->DeviceId = (PCHAR)&(newBMListPtr->DeviceIdStr); - newBMListPtr->DeviceIdLength = 4; + newBMListPtr->nVendorId = VendorID; + newBMListPtr->VendorId = (PCHAR)&(newBMListPtr->VendorIdStr); + newBMListPtr->VendorIdLength = 4; + newBMListPtr->nDeviceId = DeviceID; + newBMListPtr->DeviceId = (PCHAR)&(newBMListPtr->DeviceIdStr); + newBMListPtr->DeviceIdLength = 4; - newBMListPtr->RaidFlags = RaidFlags; + newBMListPtr->RaidFlags = RaidFlags; // } - newBMListPtr->slotNumber = slotData.u.AsULONG; - newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0; - newBMListPtr->busNumber = busNumber; + newBMListPtr->slotNumber = slotData.u.AsULONG; + newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0; + newBMListPtr->busNumber = busNumber; - newBMListPtr->NeedAltInit = NeedPciAltInit; - newBMListPtr->Known = known; + newBMListPtr->NeedAltInit = NeedPciAltInit; + newBMListPtr->Known = known; - KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit)); - } else { - KdPrint2((PRINT_PREFIX "count: BMListLen++\n")); - } + KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit)); + } else { + KdPrint2((PRINT_PREFIX "count: BMListLen++\n")); + PciDevMap[busNumber*PCI_MAX_DEVICES + slotNumber] |= (1 << funcNumber); + } - BMListLen++; - } + BMListLen++; + + } // Function + } // Slot + if(!hasPCI) { + break; } - } } if(!pass) { if(!BMListLen) @@ -650,10 +678,14 @@ BMListLen=0; } } +exit: KdPrint2((PRINT_PREFIX " BMListLen=%x\n", BMListLen)); if(deviceExtension) { ExFreePool(deviceExtension); } + if(PciDevMap) { + ExFreePool(PciDevMap); + } return(SP_RETURN_NOT_FOUND); } // end UniataEnumBusMasterController__() @@ -1621,26 +1653,11 @@ } //ioSpace = (PUCHAR)(deviceExtension->BaseIoAddress1[c]); - KdPrint2((PRINT_PREFIX "IDX_IO1 %x->%x(%s)\n", - IDX_IO1, - chan->RegTranslation[IDX_IO1].Addr, - chan->RegTranslation[IDX_IO1].MemIo ? "mem" : "io")); + DbgDumpRegTranslation(chan, IDX_IO1); + DbgDumpRegTranslation(chan, IDX_IO2); + DbgDumpRegTranslation(chan, IDX_BM_IO); + DbgDumpRegTranslation(chan, IDX_SATA_IO); - KdPrint2((PRINT_PREFIX "IDX_IO2 %x->%x(%s)\n", - IDX_IO2, - chan->RegTranslation[IDX_IO2].Addr, - chan->RegTranslation[IDX_IO2].MemIo ? "mem" : "io")); - - KdPrint2((PRINT_PREFIX "IDX_BM_IO %x->%x(%s)\n", - IDX_BM_IO, - chan->RegTranslation[IDX_BM_IO].Addr, - chan->RegTranslation[IDX_BM_IO].MemIo ? "mem" : "io")); - - KdPrint2((PRINT_PREFIX "IDX_SATA_IO %x->%x(%s)\n", - IDX_SATA_IO, - chan->RegTranslation[IDX_SATA_IO].Addr, - chan->RegTranslation[IDX_SATA_IO].MemIo ? "mem" : "io")); - if(!(deviceExtension->HwFlags & UNIATA_AHCI)) { #ifdef _DEBUG UniataDumpATARegs(chan); @@ -2302,6 +2319,9 @@ BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace; KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1)); KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2)); + if(!irq) { + KdPrint2((PRINT_PREFIX " expected InterruptLevel=%x\n", InterruptLevels[*adapterCount - 1])); + } UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); UniataInitMapBM(deviceExtension, 0, FALSE); @@ -2656,6 +2676,15 @@ KdPrint2((PRINT_PREFIX " AHCI HDD at home\n")); return ATA_AT_HOME_HDD; } + if(g_opt_VirtualMachine /*== VM_BOCHS || + g_opt_VirtualMachine == VM_VBOX*/) { + GetStatus(chan, signatureLow); + if(!signatureLow) { + KdPrint2((PRINT_PREFIX " 0-status VM - not present\n")); + UniataForgetDevice(LunExt); + return ATA_AT_HOME_NOBODY; + } + } AtapiStallExecution(10); @@ -2940,7 +2969,8 @@ RetVal = DFLAGS_DEVICE_PRESENT; LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT; LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; - } else { + } else + if(!g_opt_VirtualMachine) { // This can be ATAPI on broken hardware GetBaseStatus(chan, statusByte); if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { @@ -2950,6 +2980,9 @@ KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n", deviceNumber, statusByte)); goto try_atapi; + } else { + KdPrint2((PRINT_PREFIX "CheckDevice: VM Device %#x not present\n", + deviceNumber)); } GetBaseStatus(chan, statusByte); } Index: drivers/storage/ide/uniata/id_sata.cpp =================================================================== --- drivers/storage/ide/uniata/id_sata.cpp (revision 69690) +++ drivers/storage/ide/uniata/id_sata.cpp (working copy) @@ -576,7 +576,7 @@ } // end UniataSataIdentifyPM() -#ifdef DBG +#ifdef _DEBUG VOID NTAPI UniataDumpAhciRegs( @@ -654,7 +654,7 @@ KdPrint2((PRINT_PREFIX " UniataAhciInit:\n")); -#ifdef DBG +#ifdef _DEBUG UniataDumpAhciRegs(deviceExtension); #endif //DBG @@ -891,7 +891,7 @@ ULONG CAP; ULONG CAP2; ULONG GHC, GHC0; -#ifdef DBG +#ifdef _DEBUG ULONG BOHC; ULONG v_Mn, v_Mj; #endif //DBG @@ -919,7 +919,7 @@ deviceExtension->BaseIoAHCI_0.Addr = BaseMemAddress; deviceExtension->BaseIoAHCI_0.MemIo = MemIo; -#ifdef DBG +#ifdef _DEBUG UniataDumpAhciRegs(deviceExtension); #endif //DBG @@ -961,7 +961,7 @@ KdPrint2((PRINT_PREFIX " 64bit")); //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything } -#ifdef DBG +#ifdef _DEBUG if(CAP2 & AHCI_CAP2_BOH) { BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC); KdPrint2((PRINT_PREFIX " BOHC %#x", BOHC)); @@ -1031,7 +1031,7 @@ } KdPrint2((PRINT_PREFIX " Adjusted Channels %d\n", NumberChannels)); -#ifdef DBG +#ifdef _DEBUG v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f); v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f); @@ -1138,7 +1138,7 @@ KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI)); chan->AhciLastIS = IS.Reg; if(CI & (1 << tag)) { -#ifdef DBG +#ifdef _DEBUG UniataDumpAhciPortRegs(chan); #endif //DBG //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts @@ -1438,7 +1438,7 @@ UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg); if (timeout && (i >= timeout)) { -#ifdef DBG +#ifdef _DEBUG ULONG TFD; SError = AtapiReadPort4(chan, IDX_SATA_SError); @@ -1532,7 +1532,7 @@ KdPrint((" length/DEV_BSIZE != bcount\n")); } -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG @@ -1590,13 +1590,13 @@ AtaReq->ahci.io_cmd_flags = ahci_flags; -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb); -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG @@ -1645,7 +1645,7 @@ // KdPrint((" length/DEV_BSIZE != bcount\n")); // } -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG @@ -1700,13 +1700,13 @@ AtaReq->ahci.io_cmd_flags = ahci_flags; -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb); -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG @@ -1863,7 +1863,7 @@ } KdPrint((" TFD %#x\n", TFD)); -#ifdef DBG +#ifdef _DEBUG UniataDumpAhciPortRegs(chan); #endif // DBG @@ -2178,7 +2178,7 @@ return 0; } -#ifdef DBG +#ifdef _DEBUG KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags, AHCI_CL->cmd_table_phys)); #endif // DBG @@ -2206,12 +2206,16 @@ 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 */ + CMD0 = CMD; + CMD |= ATA_AHCI_P_CMD_ST | + ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0); + if(CMD != CMD0) { + KdPrint2((" Send CMD START\n")); + UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD); + UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */ + } else { + KdPrint2((" No CMD START, already active\n")); + } if(!ATAPI_DEVICE(chan, DeviceNumber)) { // TODO: check if we send ATAPI_RESET and wait for ready of so. @@ -2346,7 +2350,7 @@ KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel)); -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG @@ -2386,7 +2390,7 @@ ); UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */ -#ifdef DBG +#ifdef _DEBUG //UniataDumpAhciPortRegs(chan); #endif // DBG @@ -2393,7 +2397,7 @@ UniataAhciStartFR(chan); UniataAhciStart(chan); -#ifdef DBG +#ifdef _DEBUG UniataDumpAhciPortRegs(chan); #endif // DBG @@ -2571,7 +2575,7 @@ PUCHAR prd_base0; ULONGLONG prd_base64_0; }; -#ifdef DBG +#ifdef _DEBUG ULONG d; #endif // DBG @@ -2581,7 +2585,7 @@ prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK; -#ifdef DBG +#ifdef _DEBUG d = (ULONG)(prd_base64 - prd_base64_0); KdPrint2((PRINT_PREFIX " AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d)); #endif // DBG Index: drivers/storage/ide/uniata/id_sata.h =================================================================== --- drivers/storage/ide/uniata/id_sata.h (revision 69690) +++ drivers/storage/ide/uniata/id_sata.h (working copy) @@ -414,7 +414,7 @@ IN ULONG c ) { -#ifdef DBG +#ifdef _DEBUG KdPrint2((PRINT_PREFIX "imp: %#x & %#x\n", (deviceExtension)->AHCI_PI, (1<AHCI_PI) & ((ULONG)1 << c)) ? TRUE : FALSE; Index: drivers/storage/ide/uniata/srb.h =================================================================== --- drivers/storage/ide/uniata/srb.h (revision 69690) +++ drivers/storage/ide/uniata/srb.h (working copy) @@ -14,6 +14,8 @@ #ifndef _NTSRB_ #define _NTSRB_ +#pragma pack(push, 8) + // Define SCSI maximum configuration parameters. #define SCSI_MAXIMUM_LOGICAL_UNITS 8 @@ -971,4 +973,6 @@ #endif //USER_MODE +#pragma pack(pop) + #endif // Index: drivers/storage/ide/uniata/tools.h =================================================================== --- drivers/storage/ide/uniata/tools.h (revision 69690) +++ drivers/storage/ide/uniata/tools.h (working copy) @@ -34,6 +34,8 @@ #ifndef __TOOLS_H__ #define __TOOLS_H__ +#pragma pack(push, 1) + #ifdef __cplusplus extern "C" { #endif //__cplusplus @@ -109,6 +111,14 @@ KdPrint(("\n")); \ } +#define DbgDumpRegTranslation(chan, idx) \ + KdPrint2((PRINT_PREFIX \ + " IO_%#x (%#x), %s:\n", \ + idx, \ + chan->RegTranslation[idx].Addr, \ + chan->RegTranslation[idx].Proc ? "Proc" : ( \ + chan->RegTranslation[idx].MemIo ? "Mem" : "IO"))); \ + #define BrutePoint() { ASSERT(0); } #define DbgAllocatePool(x,y) ExAllocatePool(x,y) @@ -119,6 +129,8 @@ #define KdDump(a,b) {} +#define DbgDumpRegTranslation(chan, idx) {} + #define DbgAllocatePool(x,y) ExAllocatePool(x,y) #define DbgFreePool(x) ExFreePool(x) #define DbgAllocatePoolWithTag(a,b,c) ExAllocatePoolWithTag(a,b,c) @@ -183,4 +195,6 @@ #define offsetof(type, field) (ULONG)&(((type *)0)->field) #endif //offsetof +#pragma pack(pop) + #endif // __TOOLS_H__ Index: drivers/storage/ide/uniata/uniata_ver.h =================================================================== --- drivers/storage/ide/uniata/uniata_ver.h (revision 69690) +++ drivers/storage/ide/uniata/uniata_ver.h (working copy) @@ -1,10 +1,10 @@ -#define UNIATA_VER_STR "45h1" -#define UNIATA_VER_DOT 0.45.8.1 +#define UNIATA_VER_STR "45j1" +#define UNIATA_VER_DOT 0.45.10.1 #define UNIATA_VER_MJ 0 #define UNIATA_VER_MN 45 -#define UNIATA_VER_SUB_MJ 8 +#define UNIATA_VER_SUB_MJ 10 #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_DOT_COMMA 0,45,10,1 +#define UNIATA_VER_DOT_STR "0.45.10.1" #define UNIATA_VER_YEAR 2015 #define UNIATA_VER_YEAR_STR "2015"