Index: drivers/storage/ide/uniata/bsmaster.h =================================================================== --- drivers/storage/ide/uniata/bsmaster.h (revision 69313) +++ 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 @@ -1203,6 +1203,11 @@ struct _HW_DEVICE_EXTENSION* DeviceExtension; struct _HW_CHANNEL* chan; ULONG Lun; + + ULONGLONG errLastLba; + ULONG errBCount; + UCHAR errRetry; + UCHAR errPadding[3]; #ifdef IO_STATISTICS Index: drivers/storage/ide/uniata/id_ata.cpp =================================================================== --- drivers/storage/ide/uniata/id_ata.cpp (revision 69313) +++ drivers/storage/ide/uniata/id_ata.cpp (working copy) @@ -1780,13 +1780,11 @@ KdPrint2((PRINT_PREFIX "R-rate %d\n", deviceExtension->FullIdentifyData.NominalMediaRotationRate )); - KdPrint2((PRINT_PREFIX "WC %d/%d, LA %d/%d, Protected %d/%d, WB %d/%d, RB %d/%d, Q %d/%d\n", + 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.Protected, - deviceExtension->FullIdentifyData.FeaturesSupport.Protected, deviceExtension->FullIdentifyData.FeaturesEnabled.WriteBuffer, deviceExtension->FullIdentifyData.FeaturesSupport.WriteBuffer, deviceExtension->FullIdentifyData.FeaturesEnabled.ReadBuffer, @@ -1795,6 +1793,13 @@ 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, @@ -1827,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 @@ -2271,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")); @@ -2332,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; @@ -3197,9 +3217,7 @@ LunExt->MaximumBlockXfer)); } - if(LunExt->IdentifyData.MajorRevision - && 0 /* DEBUG !!!! REMOVE ME */ - ) { + if(LunExt->IdentifyData.MajorRevision) { if(LunExt->opt_ReadCacheEnable) { KdPrint2((PRINT_PREFIX " Try Enable Read Cache\n")); @@ -6723,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 Index: drivers/storage/ide/uniata/id_dma.cpp =================================================================== --- drivers/storage/ide/uniata/id_dma.cpp (revision 69313) +++ drivers/storage/ide/uniata/id_dma.cpp (working copy) @@ -2307,11 +2307,19 @@ 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 timing = 0; + switch(ChipType) { case PROLD: switch (mode) { @@ -2355,7 +2363,77 @@ if(!timing) { return; } - SetPciConfig4(0x60 + (dev<<2), timing); + 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/uniata_ver.h =================================================================== --- drivers/storage/ide/uniata/uniata_ver.h (revision 69313) +++ drivers/storage/ide/uniata/uniata_ver.h (working copy) @@ -1,10 +1,10 @@ -#define UNIATA_VER_STR "45i1" -#define UNIATA_VER_DOT 0.45.9.1 +#define UNIATA_VER_STR "45i3" +#define UNIATA_VER_DOT 0.45.9.3 #define UNIATA_VER_MJ 0 #define UNIATA_VER_MN 45 #define UNIATA_VER_SUB_MJ 9 -#define UNIATA_VER_SUB_MN 1 -#define UNIATA_VER_DOT_COMMA 0,45,9,1 -#define UNIATA_VER_DOT_STR "0.45.9.1" +#define UNIATA_VER_SUB_MN 3 +#define UNIATA_VER_DOT_COMMA 0,45,9,3 +#define UNIATA_VER_DOT_STR "0.45.9.3" #define UNIATA_VER_YEAR 2015 #define UNIATA_VER_YEAR_STR "2015"